[bb] Vertex Ambient Occlusion by DareDevil [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : Vertex Ambient Occlusion
Author : DareDevil
Posted : 1+ years ago

Description : this code is a pubblic domain, pleace specify the my name in the credits or regards this string "System Ambient Occlusion Vertex by Vincenzo Caldarulo Italy-Bari (Vincentx)"

<a href="http://www.blitzitalia.altervista.org/modules/xcgal/displayimage.php?pid=38&fullsize=1" target="_blank">http://www.blitzitalia.altervista.org/modules/xcgal/displayimage.php?pid=38&fullsize=1</a>

Excuse for my english


Code :
Code (blitzbasic) Select
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;===> Name file:
;===>
;===> Programmatore:
;===>  Caldarulo Vincenzo (Vision&Design Software)
;===> Descrizione:
;===>
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;
;
AppTitle("Ambient Occlusion Vertex by Vincentx (Vincenzo Caldarulo Italy-Bari)")
;=====================================================
;===>
Type AO_vertex
Field Vx#
Field Vy#
Field Vz#
Field Vc%
End Type

;=====================================================
;===>
Type AO_receiver
;===>
Field ObjOrig%
Field Obj%
;===>
End Type

;====>
;=====================================================
;===>
Const AO_Method% = 0 ; 0 = LinePick B3D  // 1 = LinePick SW  // 2 = Octree
Const AO_Ray# = 100
Const AO_DetBase# = 4; Level of precision AO 3 is a good result
Const AO_Detail# = (AO_DetBase+1) ;;3=4 INTERAZIONI
Const AO_TotRay# = ((4*(AO_DetBase-1)) * (AO_DetBase-1))+1
Const AO_Attenuation# = (255.0 - 64 )/AO_TotRay


;=====================================================
;===>
Dim AO_Vertex.AO_vertex(65535)
For id=0 To 65535
AO_Vertex(id) = New AO_vertex
Next
;=====================================================
;===>
Global dlr.AO_receiver

Global AO_TimeCollision=0
;Global AO_InterCollision=0

Const AO_LevelAlpha#  = 0.8
;=====================================================
;===>

Dim RayList.Point3D(AO_TotRay)
Global NSphere% = 0

;=====================================================
;===>
Precalcolo();



Graphics3D 800,600,32,2

Global Camera = CreateCamera()


LoadScene()

; =================================================================================================
; ===>
Cls
Print ">===================================================="
Print ">"
Print "> Numero di interazioni oggetto: "+AO_TotRay
Print ">"
Print ">===================================================="
Print ">"
;Stop
Local TimeAO% = AO_Update()
Global spd# = 0.5
Local l_OldTime,l_CurTime
; =================================================================================================
; ===>
Repeat

MoveEntity Camera,(KeyDown(205)-KeyDown(203))*spd,0,(MouseDown(1)-MouseDown(2))*spd
TurnEntity Camera,-MouseYSpeed()*0.1,-MouseXSpeed()*0.1,0
RotateEntity Camera,EntityPitch(Camera,True),EntityYaw(Camera,True),0

MoveMouse GraphicsWidth()*.5,GraphicsHeight()*.5

; ===========================================================================
If KeyHit(2) Then  AO_Show()
If KeyHit(3) Then  AO_Hide()


If KeyHit(24) Then  WireFrame True
If KeyHit(25) Then  WireFrame False


If (KeyDown(46)) Then
PositionEntity Camera,60,60,-60
RotateEntity Camera,30,45,0
EndIf

; ===========================================================================
; ===>
UpdateWorld()
RenderWorld()
;===>
Local Riga=0
;====>
Color 255,0,0
l_CurTime=MilliSecs()-l_OldTime
l_OldTime=MilliSecs()
Text(0,Riga,"Ms: "+l_CurTime+" AO Time: "+ TimeAO) : Riga = Riga + 10
Riga = Riga + 10 : Riga = Riga + 10
Text(0,Riga," 1 - Enable Ambient occlusion") : Riga = Riga + 10
Text(0,Riga," 2 - Disable Ambient occlusion") : Riga = Riga + 10
;===>
Flip(False)

;===>
Until KeyHit(1)

End


Function LoadScene()
;===>
Local Obj;
Local R = 20
Local R2 = 20
Local x,z
Local Segment=50
;===>
Obj = CPlane(Segment*2)
PositionEntity Obj,0,-5,0
ScaleEntity Obj, 2, 1, 2
AO_SetReceiver(Obj)
;===>
Local a#;
For a=0 To 100
;Obj = CreateSphere(16)
Obj = CreateCube()
ang = a*25.0
d0 = R2-(a/10.0)
d1 = a/3.0
PositionEntity Obj, d0*Cos(ang), d1, d0*Sin(ang)
RotateEntity Obj, 0, ang, 0
ScaleEntity Obj, 2, 2, 2

AO_SetReceiver(Obj)

Next
;===>

End Function



Function CPlane%(Number#)
;===>
If(Number>150) Then Number=150
;===>
Local mesh = CreateMesh()
Local surf = CreateSurface(mesh)
Local center#= (Number/2.0)
;===>

For pz# = 0 To Number
For px# = 0 To Number
k = AddVertex(surf, px-center, 0, pz-center, px/Number, pz/Number )
Next
Next
;===>

For pz=0 To Number-1
For px=0 To Number-1
;===>
p0 = px+((pz+0)*(Number+1))
p1 = px+((pz+0)*(Number+1))+1
p2 = px+((pz+1)*(Number+1))
p3 = px+((pz+1)*(Number+1))+1
;===>
AddTriangle(surf,p2,p1,p0)
AddTriangle(surf,p2,p3,p1)
;===>
Next
Next
;===>
Return mesh
;===>
End Function



; ==================================================
; -----------------------------------------------
; Punto 3D
;---------------------------------------
;=======================================
Type Point3D
Field x#
Field y#
Field z#
End Type

; ==================================================
; -----------------------------------------------

Function Point3DSet( Dst.Point3D, x#, y#, z#)
;---->
Dstx = x ;
Dsty = y ;
Dstz = z ;
;---->
End Function

; ==================================================
; -----------------------------------------------
; Rotazione Asse X Y
;--------------------------
;================================
Function RotateXY( Rtn.Point3D, P.Point3D, RotX%, RotY% )
; ===>
Local l_c# = Cos(RotX);
Local l_s# = Sin(RotX);
; ===>
;Rotazione Asse X
Local RX_x# =  Px
Local RX_y# = (Py * l_c)-(Pz * l_s);
Local RX_z# = (Pz * l_c)+(Py * l_s);
; ===>
l_c# = Cos(RotY);
l_s# = Sin(RotY);
; ===>
;Rotazione Asse Y
Local RY_x# = (RX_x * l_c)+(RX_z * l_s);
Local RY_y# =  RX_y
Local RY_z# = (RX_z * l_c)-(RX_x * l_s)
; ===>
Rtnx# = RY_x
Rtny# = RY_y
Rtnz# = RY_z
; ===>
End Function

; ==================================================
; -----------------------------------------------
; Calcolo della normale
;--------------------------
;================================
;
Function CalcNormalFast( Rtn.Point3D, A.Point3D, B.Point3D, C.Point3D)
; ===>
Local K1x# = Ax - Bx
Local K1y# = Ay - By
Local K1z# = Az - Bz
; ===>
Local K2x# = Bx - Cx
Local K2y# = By - Cy
Local K2z# = Bz - Cz
; ===>
; Compute their cross product.
Local Rx# = K1y#*K2z# - K1z#*K2y#
Local Ry# = K1z#*K2x# - K1x#*K2z#
Local Rz# = K1x#*K2y# - K1y#*K2x#
; ===>
Local do# = 1.0 / Sqr( (Rx*Rx) + (Ry*Ry) + (Rz*Rz) )
  ; ===>
Rtnx = Rx*do;
Rtny = Ry*do;
Rtnz = Rz*do;
;===>
End Function


; ==================================================
; -----------------------------------------------
; Vector To Angle
;--------------------------
;================================
;
Function VectorToAngle( dst.Point3D, Vect.Point3D )
  ;===>
Local dist1  = Sqr( (Vectx*Vectx)+(Vectz*Vectz)) ;
dstx = ATan2( Vecty ,dist1);
dsty = ATan2( Vectx ,Vectz);
;===>
End Function

;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;===> Name file:
;===>
;===> Programmatore:
;===>  Caldarulo Vincenzo (Vision&Design Software)
;===> Descrizione:
;===>
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;




;;=====================================================
;;===>
;Type AO_vertex
; Field Vx#
; Field Vy#
; Field Vz#
; Field Vc%
;End Type
;
;;=====================================================
;;===>
;Type AO_receiver
; ;===>
; Field ObjOrig%
; Field Obj%
; ;===>
;End Type
;
;;====>
;;=====================================================
;;===>
;Const AO_Method% = 0 ; 0 = LinePick B3D  // 1 = LinePick SW  // 2 = Octree
;Const AO_Ray# = 100
;Const AO_DetBase# = 2;
;Const AO_Detail# = (AO_DetBase+1) ;;3=4 INTERAZIONI
;Const AO_TotRay# = ((4*(AO_DetBase-1)) * (AO_DetBase-1))+1
;Const AO_Attenuation# = (255.0 - 64 )/AO_TotRay
;
;
;;=====================================================
;;===>
;Dim AO_Vertex.AO_vertex(65535)
;For id=0 To 65535
; AO_Vertex(id) = New AO_vertex
;Next
;;=====================================================
;;===>
;Global dlr.AO_receiver
;
;Global AO_TimeCollision=0
;;Global AO_InterCollision=0
;
;Const AO_LevelAlpha#  = 0.8
;;=====================================================
;;===>
;
;Dim RayList.Point3D(AO_TotRay)
;Global NSphere% = 0
;
;;=====================================================
;;===>
;Precalcolo();

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function Precalcolo()
;===>
If (AO_DetBase<=1) Then Return
;===>
NSphere%=0
Local RX#,RY#,RXa#,RYa#
Local l_Normal.Point3D = New Point3D : Point3DSet(l_Normal, 0, AO_Ray, 0)
Local l_PartRY# = ((AO_DetBase-1)*4)
Local l_AngS# = 360 / l_PartRY ;
Local l_AngT# = 90.0 / AO_DetBase
;===>
For RY=0 To l_PartRY-1
;===>
RYa# = l_AngS*RY
;===>
For RX=1 To AO_DetBase-1
;===>
RXa# = RX*l_AngT
;===>
RayList.Point3D(NSphere) = New Point3D
;===>
RotateXY(RayList(NSphere),l_Normal, RXa, RYa)
;===>
NSphere = NSphere+1
;===>
Next
;===>
Next
;===>
Delete l_Normal
;===>
End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Free()
Local l_AO_Recived.AO_receiver
For l_AO_Recived.AO_receiver = Each AO_receiver
FreeEntity l_AO_RecivedObj
Delete l_AO_Recived
Next

End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_SetReceiver(mesh, ShadowEnable=True, TexAlpha=0)
;===>
Local l_AO_Recived.AO_receiver = New AO_receiver
;===>
l_AO_RecivedObjOrig = mesh
l_AO_RecivedObj = CopyMesh(l_AO_RecivedObjOrig,l_AO_RecivedObjOrig)
NameEntity( l_AO_RecivedObj, EntityName(l_AO_RecivedObjOrig))
EntityAlpha l_AO_RecivedObj, AO_LevelAlpha
EntityBlend l_AO_RecivedObj, 2

;
EntityPickMode(l_AO_RecivedObj,2)
;===>
EntityFX l_AO_RecivedObj,2+1
UpdateNormals l_AO_RecivedObj
;===>
End Function


;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Update()
;===>
Local l_total_tris%,l_total_vert%
Local Total_ColliTime = 0
;===>
Local Start_Time=MilliSecs()
;===>
Local l_IdV0c%, l_IdV0x#, l_IdV0y#, l_IdV0z#, l_IdV0.AO_vertex
Local l_IdV1c%, l_IdV1x#, l_IdV1y#, l_IdV1z#, l_IdV1.AO_vertex
Local l_IdV2c%, l_IdV2x#, l_IdV2y#, l_IdV2z#, l_IdV2.AO_vertex
;===>
Local l_Point0.Point3D = New Point3D
Local l_Point1.Point3D = New Point3D
Local l_Point2.Point3D = New Point3D
;===>
Local l_Normal.Point3D = New Point3D : Point3DSet(l_Normal, 0, AO_Ray, 0)
Local l_NorMod.Point3D = New Point3D
Local l_Angles.Point3D = New Point3D
;===>
Local SphereList=0
Local v%, s%
;===>
Local l_CurObj;
Local n_surfs
Local surf, n_tris
Local Px#,Py#,Pz#;
;===>
Local Color_a# = 0
Local l_rX#,l_rY#
;===>
Local cnt=0
Local l_AO_Recived.AO_receiver
Local Riga$
;===>
Local RYa#,RXa#
Start_Time=MilliSecs()
Local Start_ms=Start_Time

Local l_CurVert.AO_vertex
Local aamod
;===>
For l_AO_Recived = Each AO_receiver
; ===>
l_CurObj = l_AO_RecivedObj
; ===>
n_surfs= CountSurfaces(l_CurObj)
Local l_NewId%=0;
Print "> Oggetto: "+cnt+" Name: "+EntityName(l_CurObj)

cnt=cnt+1
;===>
For s = 1 To n_surfs
;===>
surf = GetSurface(l_CurObj,s)
n_tris = CountTriangles(surf)-1
aamod = n_tris * .2
If aamod=0 Then aamod=1
;===>
If (n_tris>0) Then
;===>
Local l_NVert = CountVertices(surf)-1
;===>
l_total_vert = l_total_vert+l_NVert
l_total_tris = l_total_tris+n_tris
;===>
For v = 0 To l_NVert
;===>
l_CurVert = AO_Vertex(v)
TFormPoint VertexX( surf, v ), VertexY( surf, v ), VertexZ( surf, v ), l_CurObj, 0
l_CurVertVx = TFormedX()
l_CurVertVy = TFormedY()
l_CurVertVz = TFormedZ()
l_CurVertVc = 255;
Next
;===>
For v = 0 To n_tris
; ===>
l_IdV0 = AO_Vertex(TriangleVertex ( surf, v, 0 ))
l_IdV1 = AO_Vertex(TriangleVertex ( surf, v, 1 ))
l_IdV2 = AO_Vertex(TriangleVertex ( surf, v, 2 ))
; ===>
l_IdV0x = l_IdV0Vx ; Vertexx (surf,l_IdV0)
l_IdV0y = l_IdV0Vy ; VertexY (surf,l_IdV0)
l_IdV0z = l_IdV0Vz ; VertexZ (surf,l_IdV0)
l_IdV0c = l_IdV0Vc ; VertexRed (surf,l_IdV0)
;===>
l_IdV1x = l_IdV1Vx ;
l_IdV1y = l_IdV1Vy ;
l_IdV1z = l_IdV1Vz ;
l_IdV1c = l_IdV1Vc ;
;===>
l_IdV2x = l_IdV2Vx ;
l_IdV2y = l_IdV2Vy ;
l_IdV2z = l_IdV2Vz ;
l_IdV2c = l_IdV2Vc ;
;===>
Px = (l_IdV0x + l_IdV1x + l_IdV2x) * .3333333
Py = (l_IdV0y + l_IdV1y + l_IdV2y) * .3333333
Pz = (l_IdV0z + l_IdV1z + l_IdV2z) * .3333333
;===>
l_Point0x = l_IdV0x : l_Point0y = l_IdV0y : l_Point0z = l_IdV0z;
l_Point1x = l_IdV1x : l_Point1y = l_IdV1y : l_Point1z = l_IdV1z;
l_Point2x = l_IdV2x : l_Point2y = l_IdV2y : l_Point2z = l_IdV2z;
;===>

l_NorModx = VertexNX(surf,TriangleVertex ( surf, v, 0 ))
l_NorMody = VertexNY(surf,TriangleVertex ( surf, v, 0 ))
l_NorModz = VertexNZ(surf,TriangleVertex ( surf, v, 0 ))
CalcNormalFast(l_NorMod, l_Point0, l_Point1, l_Point2);
VectorToAngle(l_Angles,l_NorMod)
;===>
l_rX# = l_Anglesx + 270 ;
l_rY# = l_Anglesy + 180 ;
;===>
Color_a = 255
; =========================================================================================================
; ----------------------------------------------------------------------------------------------------
; Solution 2  
; ===>
;
; ===>
; Asse perpedicolare al piano
l_NorModx = l_NorModx*AO_Ray : l_NorMody = l_NorMody*AO_Ray : l_NorModz = l_NorModz*AO_Ray
; ===>

LinePick(Px, Py, Pz, l_NorModx, l_NorMody, l_NorModz);
If (PickedEntity()<>0) Then Color_a = Color_a - AO_Attenuation
; ===>
Total_ColliTime = Total_ColliTime + AO_TimeCollision
; ===>
If (AO_DetBase>1) Then
;===>
For SphereList=0 To NSphere-1
;===>
RotateXY(l_NorMod, RayList(SphereList), l_rX, l_rY)
;===>
LinePick(Px, Py, Pz, l_NorModx, l_NorMody, l_NorModz);
If (PickedEntity()<>0) Then Color_a = Color_a - AO_Attenuation
;===>
Next
; ===>
EndIf
;===>
Total_ColliTime = Total_ColliTime + AO_TimeCollision
;===>
;----------------------------------------------------------------------------------------------------
;=========================================================================================================
;===>

If ( Color_a < l_IdV0c) Then l_IdV0Vc = Color_a
If ( Color_a < l_IdV1c) Then l_IdV1Vc = Color_a
If ( Color_a < l_IdV2c) Then l_IdV2Vc = Color_a
;===>
If ((v Mod aamod)=0) Then
;===>
Riga$ =         "> Surfaces:    " + Float(Int((Float(s)/Float(n_surfs))*10000))/100.0
Riga$ = Riga$ + "% Complete:    " + Float(Int((Float(v)/Float(n_tris ))*10000))/100.0
Riga$ = Riga$ + "  TimeCol:     " + Total_ColliTime
Riga$ = Riga$ + "  TotalTime:   " + (MilliSecs()-Start_ms)
Print Riga$
;===>
Total_ColliTime = 0
Start_ms=MilliSecs()
;===>
EndIf
;===>
Next
;===>
For v = 0 To l_NVert
;===>
Color_a = AO_Vertex(v)Vc
VertexColor surf, v, Color_a, Color_a, Color_a;
;===>
Next
;===>
Riga$ =         "> Surfaces:    " + Float(Int((Float(s)/Float(n_surfs))*10000))/100.0
Riga$ = Riga$ + "% Complete:    " + 100.0
Riga$ = Riga$ + "  TimeCol:     " + Total_ColliTime
Riga$ = Riga$ + "  TotalTime:   " + (MilliSecs()-Start_ms)
Print Riga$
;===>
Total_ColliTime = 0
Start_ms=MilliSecs()
;===>
EndIf
;===>
Print " "
l_NewId = l_NewId + CountVertices(surf)
;===>
Next
Next
;===>
Delete l_Point0
Delete l_Point1
Delete l_Point2

Delete l_Normal;
Delete l_NorMod;
Delete l_Angles;
;===>
Local Stop_Time% = MilliSecs()-Start_Time
;===>
Print "->"
Print "-> Total Time collision: "+Stop_Time
Print "->"
Print " Total Tris: "+l_total_tris
Print " Total Vert: "+l_total_vert
Print "->"
Print " "
Print "Press any Key"
WaitKey()
;===>
Return Stop_Time
;===>
End Function



;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Show()
;===>
Local l_AO_Recived.AO_receiver
;===>
For l_AO_Recived.AO_receiver = Each AO_receiver
; ===>
ShowEntity l_AO_RecivedObj
; ===>
Next
;===>
End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Hide()
;===>
Local l_AO_Recived.AO_receiver
;===>
For l_AO_Recived.AO_receiver = Each AO_receiver
; ===>
HideEntity l_AO_RecivedObj
; ===>
Next
;===>
End Function


;~IDEal Editor Parameters:
;~C#Blitz3D


Comments :


N(Posted 1+ years ago)

 <div class="quote"> this code is a pubblic domain if specify the my name in the credits the string to be included is "System Ambient Occlusion Vertex by Vincenzo Caldarulo Italy-Bari (Vincentx)" </div>Unfortunately, you've already made it public domain, so it's that way regardless of whether or not you're credited.  I suspect most people would be happy to do that though (otherwise there are plenty of four-letter words to describe those individuals).


DareDevil(Posted 1+ years ago)

 ok tnk ;)


Matty(Posted 1+ years ago)

 I must be missing something but that code does not look complete?


DareDevil(Posted 1+ years ago)

 .....


Matty(Posted 1+ years ago)

 eh?


DareDevil(Posted 1+ years ago)

 Ok i have update the codebye


Matty(Posted 1+ years ago)

 Ahh I see, thanks.


DareDevil(Posted 1+ years ago)

 The new Update whitc load and save automatic the ambent vertex occlusion. the best regards RifRaf for wirite function Load and Write
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;===> Name file:
;===>
;===> Programmatore:
;===>  Caldarulo Vincenzo (Vision&Design Software)
;===> Descrizione:
;===>
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;
;
AppTitle("Ambient Occlusion Vertex by Vincentx (Vincenzo Caldarulo Italy-Bari)")
;=====================================================
;===>
Type AO_vertex
Field Vx#
Field Vy#
Field Vz#
Field Vc%
End Type

;=====================================================
;===>
Type AO_receiver
;===>
Field ObjOrig%
Field Obj%
Field FileName$
;===>
End Type

;====>
;=====================================================
;===>
Const AO_Method% = 0 ; 0 = LinePick B3D  // 1 = LinePick SW  // 2 = Octree
Const AO_Ray# =120 ; Lenght of ray
Const AO_DetBase# = 4; Level of precision AO 3 is a good result
Const AO_Detail# = (AO_DetBase+1) ;;3=4 INTERAZIONI
Const AO_TotRay# = ((4*(AO_DetBase-1)) * (AO_DetBase-1))+1
Const AO_Attenuation# = (255.0 - 1 )/AO_TotRay


;=====================================================
;===>
Dim AO_Vertex.AO_vertex(65535)
For id=0 To 65535
AO_Vertex(id) = New AO_vertex
Next
;=====================================================
;===>
Global dlr.AO_receiver

Global AO_TimeCollision=0
;Global AO_InterCollision=0

Const AO_LevelAlpha#  = 0.8
;=====================================================
;===>

Dim RayList.Point3D(AO_TotRay)
Global NSphere% = 0

;=====================================================
;===>
Precalcolo();


Global spd# = 0.5

Graphics3D 800,600,32,2
;AmbientLight 255,255,255
; GameLight=CreateLight():RotateEntity gamelight,0,0,35
; LightColor gamelight,200,200,200
ClearTextureFilters()
Global Camera = CreateCamera()


LoadScene()

; =================================================================================================
; ===>
Cls
Print ">===================================================="
Print ">"
Print "> Numero di interazioni oggetto: "+AO_TotRay
Print ">"
Print ">===================================================="
Print ">"
;Stop
Local TimeAO% = AO_Update()
spd# = 0.5
Local l_OldTime,l_CurTime
; =================================================================================================
; ===>


Repeat
MoveEntity Camera,(KeyDown(205)-KeyDown(203))*spd,0,(MouseDown(1)-MouseDown(2))*spd
TurnEntity Camera,-MouseYSpeed()*0.1,-MouseXSpeed()*0.1,0
RotateEntity Camera,EntityPitch(Camera,True),EntityYaw(Camera,True),0

MoveMouse GraphicsWidth()*.5,GraphicsHeight()*.5

; ===========================================================================
If KeyHit(2) Then  AO_Show()
If KeyHit(3) Then  AO_Hide()

If KeyHit(24) Then  WireFrame True
If KeyHit(25) Then  WireFrame False


If (KeyDown(46)) Then
PositionEntity Camera,60,60,-60
RotateEntity Camera,30,45,0
EndIf

; ===========================================================================
; ===>
UpdateWorld()
RenderWorld()
;===>
Local Riga=0
;====>
Color 255,0,0
l_CurTime=MilliSecs()-l_OldTime
l_OldTime=MilliSecs()
Text(0,Riga,"Ms: "+l_CurTime+" AO Time: "+ TimeAO) : Riga = Riga + 10
Riga = Riga + 10 : Riga = Riga + 10
Text(0,Riga," 1 - Enable Ambient occlusion") : Riga = Riga + 10
Text(0,Riga," 2 - Disable Ambient occlusion") : Riga = Riga + 10
;===>
Flip(False)

;===>
Until KeyHit(1)

End


Function LoadScene()
;===>
Local Obj;
Local R = 20
Local R2 = 20
Local x,z
Local Segment=50
;===>
Obj = CPlane(Segment*2)
PositionEntity Obj,0,-5,0
ScaleEntity Obj, 2, 1, 2
        CreateDir("AO_DIR");
AO_SetReceiver(Obj,"AO_DIRAO_plane.aof") ; .aof ambient occlusion file
;===>
Local a#;
For a=0 To 100
;Obj = CreateSphere(16)
Obj = CreateCube()
ang = a*25.0
d0 = R2-(a/10.0)
d1 = a/3.0
PositionEntity Obj, d0*Cos(ang), d1, d0*Sin(ang)
RotateEntity Obj, 0, ang, 0
ScaleEntity Obj, 2, 2, 2

AO_SetReceiver(Obj,"AO_DIRAO_cube"+a+".aof")

Next
;===>


End Function



Function CPlane%(Number#)
;===>
If(Number>150) Then Number=150
;===>
Local mesh = CreateMesh()
Local surf = CreateSurface(mesh)
Local center#= (Number/2.0)
;===>

For pz# = 0 To Number
For px# = 0 To Number
k = AddVertex(surf, px-center, 0, pz-center, px/Number, pz/Number )
Next
Next
;===>

For pz=0 To Number-1
For px=0 To Number-1
;===>
p0 = px+((pz+0)*(Number+1))
p1 = px+((pz+0)*(Number+1))+1
p2 = px+((pz+1)*(Number+1))
p3 = px+((pz+1)*(Number+1))+1
;===>
AddTriangle(surf,p2,p1,p0)
AddTriangle(surf,p2,p3,p1)
;===>
Next
Next
;===>
Return mesh
;===>
End Function



; ==================================================
; -----------------------------------------------
; Punto 3D
;---------------------------------------
;=======================================
Type Point3D
Field x#
Field y#
Field z#
End Type

; ==================================================
; -----------------------------------------------

Function Point3DSet( Dst.Point3D, x#, y#, z#)
;---->
Dstx = x ;
Dsty = y ;
Dstz = z ;
;---->
End Function

; ==================================================
; -----------------------------------------------
; Rotazione Asse X Y
;--------------------------
;================================
Function RotateXY( Rtn.Point3D, P.Point3D, RotX%, RotY% )
; ===>
Local l_c# = Cos(RotX);
Local l_s# = Sin(RotX);
; ===>
;Rotazione Asse X
Local RX_x# =  Px
Local RX_y# = (Py * l_c)-(Pz * l_s);
Local RX_z# = (Pz * l_c)+(Py * l_s);
; ===>
l_c# = Cos(RotY);
l_s# = Sin(RotY);
; ===>
;Rotazione Asse Y
Local RY_x# = (RX_x * l_c)+(RX_z * l_s);
Local RY_y# =  RX_y
Local RY_z# = (RX_z * l_c)-(RX_x * l_s)
; ===>
Rtnx# = RY_x
Rtny# = RY_y
Rtnz# = RY_z
; ===>
End Function

; ==================================================
; -----------------------------------------------
; Calcolo della normale
;--------------------------
;================================
;
Function CalcNormalFast( Rtn.Point3D, A.Point3D, B.Point3D, C.Point3D)
; ===>
Local K1x# = Ax - Bx
Local K1y# = Ay - By
Local K1z# = Az - Bz
; ===>
Local K2x# = Bx - Cx
Local K2y# = By - Cy
Local K2z# = Bz - Cz
; ===>
; Compute their cross product.
Local Rx# = K1y#*K2z# - K1z#*K2y#
Local Ry# = K1z#*K2x# - K1x#*K2z#
Local Rz# = K1x#*K2y# - K1y#*K2x#
; ===>
Local do# = 1.0 / Sqr( (Rx*Rx) + (Ry*Ry) + (Rz*Rz) )
  ; ===>
Rtnx = Rx*do;
Rtny = Ry*do;
Rtnz = Rz*do;
;===>
End Function


; ==================================================
; -----------------------------------------------
; Vector To Angle
;--------------------------
;================================
;
Function VectorToAngle( dst.Point3D, Vect.Point3D )
  ;===>
Local dist1  = Sqr( (Vectx*Vectx)+(Vectz*Vectz)) ;
dstx = ATan2( Vecty ,dist1);
dsty = ATan2( Vectx ,Vectz);
;===>
End Function

;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;===> Name file:
;===>
;===> Programmatore:
;===>  Caldarulo Vincenzo (Vision&Design Software)
;===> Descrizione:
;===>
;===>O=========================o<=================================================================
;===>O=========================o<=================================================================
;




;;=====================================================
;;===>
;Type AO_vertex
; Field Vx#
; Field Vy#
; Field Vz#
; Field Vc%
;End Type
;
;;=====================================================
;;===>
;Type AO_receiver
; ;===>
; Field ObjOrig%
; Field Obj%
; ;===>
;End Type
;
;;====>
;;=====================================================
;;===>
;Const AO_Method% = 0 ; 0 = LinePick B3D  // 1 = LinePick SW  // 2 = Octree
;Const AO_Ray# = 100
;Const AO_DetBase# = 2;
;Const AO_Detail# = (AO_DetBase+1) ;;3=4 INTERAZIONI
;Const AO_TotRay# = ((4*(AO_DetBase-1)) * (AO_DetBase-1))+1
;Const AO_Attenuation# = (255.0 - 64 )/AO_TotRay
;
;
;;=====================================================
;;===>
;Dim AO_Vertex.AO_vertex(65535)
;For id=0 To 65535
; AO_Vertex(id) = New AO_vertex
;Next
;;=====================================================
;;===>
;Global dlr.AO_receiver
;
;Global AO_TimeCollision=0
;;Global AO_InterCollision=0
;
;Const AO_LevelAlpha#  = 0.8
;;=====================================================
;;===>
;
;Dim RayList.Point3D(AO_TotRay)
;Global NSphere% = 0
;
;;=====================================================
;;===>
;Precalcolo();

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function Precalcolo()
;===>
If (AO_DetBase<=1) Then Return
;===>
NSphere%=0
Local RX#,RY#,RXa#,RYa#
Local l_Normal.Point3D = New Point3D : Point3DSet(l_Normal, 0, AO_Ray, 0)
Local l_PartRY# = ((AO_DetBase-1)*4)
Local l_AngS# = 360 / l_PartRY ;
Local l_AngT# = 90.0 / AO_DetBase
;===>
For RY=0 To l_PartRY-1
;===>
RYa# = l_AngS*RY
;===>
For RX=1 To AO_DetBase-1
;===>
RXa# = RX*l_AngT
;===>
RayList.Point3D(NSphere) = New Point3D
;===>
RotateXY(RayList(NSphere),l_Normal, RXa, RYa)
;===>
NSphere = NSphere+1
;===>
Next
;===>
Next
;===>
Delete l_Normal
;===>
End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Free()
Local l_AO_Recived.AO_receiver
For l_AO_Recived.AO_receiver = Each AO_receiver
FreeEntity l_AO_RecivedObj
Delete l_AO_Recived
Next

End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_SetReceiver(mesh, AO_FileName$)
;===>
Local l_AO_Recived.AO_receiver = New AO_receiver
;===>

l_AO_RecivedFileName = AO_FileName;
l_AO_RecivedObjOrig = mesh
l_AO_RecivedObj = CopyMesh(l_AO_RecivedObjOrig,l_AO_RecivedObjOrig)
NameEntity( l_AO_RecivedObj, EntityName(l_AO_RecivedObjOrig))
EntityAlpha l_AO_RecivedObj, AO_LevelAlpha
EntityBlend l_AO_RecivedObj, 1
;
EntityPickMode(l_AO_RecivedObj,2)
;===>
EntityFX l_AO_RecivedObj,2+1+32
UpdateNormals l_AO_RecivedObj
;===>
Return l_AO_RecivedObj
End Function


;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Update()
;===>
Local l_total_tris%,l_total_vert%
Local Total_ColliTime = 0
;===>
Local Start_Time=MilliSecs()
;===>
Local l_IdV0c%, l_IdV0x#, l_IdV0y#, l_IdV0z#, l_IdV0.AO_vertex
Local l_IdV1c%, l_IdV1x#, l_IdV1y#, l_IdV1z#, l_IdV1.AO_vertex
Local l_IdV2c%, l_IdV2x#, l_IdV2y#, l_IdV2z#, l_IdV2.AO_vertex
;===>
Local l_Point0.Point3D = New Point3D
Local l_Point1.Point3D = New Point3D
Local l_Point2.Point3D = New Point3D
;===>
Local l_Normal.Point3D = New Point3D : Point3DSet(l_Normal, 0, AO_Ray, 0)
Local l_NorMod.Point3D = New Point3D
Local l_Angles.Point3D = New Point3D
;===>
Local SphereList=0
Local v%, s%
;===>
Local l_CurObj;
Local n_surfs
Local surf, n_tris
Local Px#,Py#,Pz#;
;===>
Local Color_a# = 0
Local l_rX#,l_rY#
;===>
Local cnt=0
Local l_AO_Recived.AO_receiver
Local Riga$
;===>
Local RYa#,RXa#
Start_Time=MilliSecs()
Local Start_ms=Start_Time

Local l_CurVert.AO_vertex
Local aamod
;===>
For l_AO_Recived = Each AO_receiver
; ===>
l_CurObj = l_AO_RecivedObj
;exsist the file AO for object
If FileType(l_AO_RecivedFileName)=1 Then
;===>
AO_LoadFile(l_CurObj,l_AO_RecivedFileName);
;===>
Else
; ===>
n_surfs= CountSurfaces(l_CurObj)
Local l_NewId%=0;
Print "> Oggetto: "+cnt+" Name: "+EntityName(l_CurObj)

cnt=cnt+1
;===>
For s = 1 To n_surfs
;===>
surf = GetSurface(l_CurObj,s)
n_tris = CountTriangles(surf)-1
aamod = n_tris * .2
If aamod=0 Then aamod=1
;===>
If (n_tris>0) Then
;===>
Local l_NVert = CountVertices(surf)-1
;===>
l_total_vert = l_total_vert+l_NVert
l_total_tris = l_total_tris+n_tris
;===>
For v = 0 To l_NVert
;===>
l_CurVert = AO_Vertex(v)
TFormPoint VertexX( surf, v ), VertexY( surf, v ), VertexZ( surf, v ), l_CurObj, 0
l_CurVertVx = TFormedX()
l_CurVertVy = TFormedY()
l_CurVertVz = TFormedZ()
l_CurVertVc = 255;
Next
;===>
For v = 0 To n_tris
; ===>
l_IdV0 = AO_Vertex(TriangleVertex ( surf, v, 0 ))
l_IdV1 = AO_Vertex(TriangleVertex ( surf, v, 1 ))
l_IdV2 = AO_Vertex(TriangleVertex ( surf, v, 2 ))
; ===>
l_IdV0x = l_IdV0Vx ; Vertexx (surf,l_IdV0)
l_IdV0y = l_IdV0Vy ; VertexY (surf,l_IdV0)
l_IdV0z = l_IdV0Vz ; VertexZ (surf,l_IdV0)
l_IdV0c = l_IdV0Vc ; VertexRed (surf,l_IdV0)
;===>
l_IdV1x = l_IdV1Vx ;
l_IdV1y = l_IdV1Vy ;
l_IdV1z = l_IdV1Vz ;
l_IdV1c = l_IdV1Vc ;
;===>
l_IdV2x = l_IdV2Vx ;
l_IdV2y = l_IdV2Vy ;
l_IdV2z = l_IdV2Vz ;
l_IdV2c = l_IdV2Vc ;
;===>
Px = (l_IdV0x + l_IdV1x + l_IdV2x) * .3333333
Py = (l_IdV0y + l_IdV1y + l_IdV2y) * .3333333
Pz = (l_IdV0z + l_IdV1z + l_IdV2z) * .3333333
;===>
l_Point0x = l_IdV0x : l_Point0y = l_IdV0y : l_Point0z = l_IdV0z;
l_Point1x = l_IdV1x : l_Point1y = l_IdV1y : l_Point1z = l_IdV1z;
l_Point2x = l_IdV2x : l_Point2y = l_IdV2y : l_Point2z = l_IdV2z;
;===>

l_NorModx = VertexNX(surf,TriangleVertex ( surf, v, 0 ))
l_NorMody = VertexNY(surf,TriangleVertex ( surf, v, 0 ))
l_NorModz = VertexNZ(surf,TriangleVertex ( surf, v, 0 ))
CalcNormalFast(l_NorMod, l_Point0, l_Point1, l_Point2);
VectorToAngle(l_Angles,l_NorMod)
;===>
l_rX# = l_Anglesx + 270 ;
l_rY# = l_Anglesy + 180 ;
;===>
Color_a = 255
; =========================================================================================================
; ----------------------------------------------------------------------------------------------------
; Solution 2  
; ===>
;
; ===>
; Asse perpedicolare al piano
l_NorModx = l_NorModx*AO_Ray : l_NorMody = l_NorMody*AO_Ray : l_NorModz = l_NorModz*AO_Ray
; ===>

LinePick(Px, Py, Pz, l_NorModx, l_NorMody, l_NorModz);
If (PickedEntity()<>0) Then Color_a = Color_a - AO_Attenuation
; ===>
Total_ColliTime = Total_ColliTime + AO_TimeCollision
; ===>
If (AO_DetBase>1) Then
;===>
For SphereList=0 To NSphere-1
;===>
RotateXY(l_NorMod, RayList(SphereList), l_rX, l_rY)
;===>
LinePick(Px, Py, Pz, l_NorModx, l_NorMody, l_NorModz);
If (PickedEntity()<>0) Then Color_a = Color_a - AO_Attenuation
;===>
Next
; ===>
EndIf
;===>
Total_ColliTime = Total_ColliTime + AO_TimeCollision
;===>
;----------------------------------------------------------------------------------------------------
;=========================================================================================================
;===>

If ( Color_a < l_IdV0c) Then l_IdV0Vc = Color_a
If ( Color_a < l_IdV1c) Then l_IdV1Vc = Color_a
If ( Color_a < l_IdV2c) Then l_IdV2Vc = Color_a
;===>
If ((v Mod aamod)=0) Then
;===>
Riga$ =         "> Surfaces:    " + Float(Int((Float(s)/Float(n_surfs))*10000))/100.0
Riga$ = Riga$ + "% Complete:    " + Float(Int((Float(v)/Float(n_tris ))*10000))/100.0
Riga$ = Riga$ + "  TimeCol:     " + Total_ColliTime
Riga$ = Riga$ + "  TotalTime:   " + (MilliSecs()-Start_ms)
Print Riga$
;===>
Total_ColliTime = 0
Start_ms=MilliSecs()
;===>
EndIf
;===>
Next
;===>
For v = 0 To l_NVert
;===>
Color_a = AO_Vertex(v)Vc
VertexColor surf, v, Color_a, Color_a, Color_a;
;===>
Next
;===>
Riga$ =         "> Surfaces:    " + Float(Int((Float(s)/Float(n_surfs))*10000))/100.0
Riga$ = Riga$ + "% Complete:    " + 100.0
Riga$ = Riga$ + "  TimeCol:     " + Total_ColliTime
Riga$ = Riga$ + "  TotalTime:   " + (MilliSecs()-Start_ms)
Print Riga$
;===>
Total_ColliTime = 0
Start_ms=MilliSecs()
;===>
EndIf
;===>
Print " "
l_NewId = l_NewId + CountVertices(surf)
;===>
Next
;===>
AO_SaveFile(l_CurObj, l_AO_RecivedFileName);
;===>
EndIf
;===>
Next
;===>
Delete l_Point0
Delete l_Point1
Delete l_Point2

Delete l_Normal;
Delete l_NorMod;
Delete l_Angles;
;===>
Local Stop_Time% = MilliSecs()-Start_Time
;===>
Print "->"
Print "-> Total Time collision: "+Stop_Time
Print "->"
Print " Total Tris: "+l_total_tris
Print " Total Vert: "+l_total_vert
Print "->"
Print " "
Print "Press any Key"
WaitKey()
;===>
Return Stop_Time
;===>
End Function



;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Show()
;===>
Local l_AO_Recived.AO_receiver
;===>
For l_AO_Recived.AO_receiver = Each AO_receiver
; ===>
ShowEntity l_AO_RecivedObj
; ===>
Next
;===>
End Function

;=====================================================
;--------------------------------------------------
;===>
;
;===>
;
Function AO_Hide()
;===>
Local l_AO_Recived.AO_receiver
;===>
For l_AO_Recived.AO_receiver = Each AO_receiver
; ===>
HideEntity l_AO_RecivedObj
; ===>
Next
;===>
End Function


Function AO_SaveFile( Mesh, AO_FileName$)
;===>
EntityFX Mesh,2+1
;===>
;first record the surface count
Local scount=CountSurfaces(Mesh)
Local F=WriteFile(AO_FileName$)
WriteInt F,scount
;===>
  For s=1 To scount
;===>
    Local surf=GetSurface(Mesh,s)
    Local vcount=CountVertices(surf)-1
  ;===>
; surfaces can get rearranged if the model is reexported via differnt modelling apps.. so lets
    ; record the surface info here so we can find the matching surface when we reload the map
WriteInt F,s
WriteInt F,vcount
WriteInt F,CountTriangles(surf) ; just here to help make a surface match in the loader
For v=0 To vcount
; Now save the vertex data
; since we are not using colored lights, we need only save the red channel
; on reload we apply the red channel to all r,g and b  
WriteFloat F,VertexRed(surf,v)
WriteFloat F,VertexGreen(surf,v)
WriteFloat F,VertexBlue(surf,v)
Next
  Next
CloseFile F
End Function                    

Function AO_LoadFile( Mesh, AO_FileName$)
EntityBlend Mesh, 1
EntityFX Mesh,2+1

If FileType(AO_FileName$)<>1 Then Return -1
Local f=OpenFile(AO_FileName$)
Local scount=ReadInt(f)
Local surfcount=CountSurfaces(Mesh)
;===>
;make sure we have at least the needed suface count
If scount<>surfcount Then
CloseFile f
Return -1
EndIf
;===>
For i=1 To scount
;read vert count and tri count
Local SurfID=ReadInt(f)
Local vcount=ReadInt(f)
Local tricount=ReadInt(f)
;find a matching surface
Local match=0
;===>
;first lets try the surface stored in the save. but because surfaces can get rearranged if a model is reexported
    ;we wont assume its in the same order it was in when we saved the ambient map
    Local s=GetSurface(Mesh,SurfID)
If vcount=(CountVertices(s)-1) And tricount=CountTriangles(s) Then
match=1
For Vert=0 To vcount
vr=ReadFloat(f)
vg=ReadFloat(f)
vb=ReadFloat(f)
VertexColor s,vert,vr,vg,vb
Next
EndIf
;===>
; if its not in the right order then match may = 0, if it does
    ; then we want to search though all the surfaces and find the right one    
    If match=0 Then
For getsurf=1 To scount
s=GetSurface(Mesh,getsurf)
If vcount=(CountVertices(s)-1) And tricount=CountTriangles(s) Then
match=1
For Vert=0 To vcount
vr=ReadFloat(f)
vg=ReadFloat(f)
vb=ReadFloat(f)
VertexColor s,vert,vr,vg,vb,VertexAlpha(s,vert)
Next
EndIf
Next
    EndIf
;===>
    ;if match still is 0, it means there was no matching surface and the model has changed its gemoetric properties
If match=0 Then
   CloseFile f
Return -1 ; did not find a matching surface for this data
EndIf
;===>
Next
;===>
CloseFile f
UpdateNormals Mesh
Return 1
;===>

End Function

;~IDEal Editor Parameters:
;~F#2B6#2C8
;~C#Blitz3D



RifRaf(Posted 1+ years ago)

 just a few things In your new example you included a folder name in the save and load filepath.   This will mav on anyone else because the folder does not exist.You left the AO_DetBase# = 2, people should crank it to at least 4 to see some detail in the results.


DareDevil(Posted 1+ years ago)

 ok ! have update the codebye


Oiduts Studios(Posted 1+ years ago)

 Is it possible to have a texture on the mesh and ambient occlusion? I can't seem to find a free method to pre-bake ao maps. [/i]