For type # PB_Mesh_TriangleList it takes 3 consecutive index to define a triangle.
.
is loaded from a file, the type is necessarily # PB_Mesh_TriangleList.
Code: Select all
IncludeFile "Screen3DRequester.pb"
Structure Vector3
x.f
y.f
z.f
EndStructure
Macro SubVector3(n, v, w)
n\x = v\x - w\x
n\y = v\y - w\y
n\z = v\z - w\z
EndMacro
Define.Vector3 Normal, v1, v2, v3
#CameraSpeed = 1
#NbX=30
#NbZ=30
Global.f AngleVague, WaveFrequency, WavePeriodX, WavePeriodZ, WaveAmplitude
WaveFrequency=3 ;=waves/second
WavePeriodX =9 ;=1/Wave lenght
WavePeriodZ =11 ;=1/Wave lenght
WaveAmplitude=3
Define.f KeyX, KeyY, MouseX, MouseY
Global Dim MeshData.PB_MeshVertex(0)
Global Dim MeshDataInd.PB_MeshFace(0)
Declare UpdateMatrix()
Declare CreateMatrix()
If InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Packs/skybox.zip", #PB_3DArchive_Zip)
Add3DArchive("Data/Scripts", #PB_3DArchive_FileSystem)
Parse3DScripts()
;-Material
CreateMaterial(1, LoadTexture(1, "MRAMOR6X6.jpg"))
MaterialCullingMode(1, 1)
;-Mesh
CreateMatrix()
;-Camera
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0,0,150,80, #PB_Absolute)
CameraLookAt(0, 0, 0, 0)
CameraBackColor(0, RGB(90, 0, 0))
;-Light
CreateLight(0, RGB(255, 255, 255), 5, 15, 5)
AmbientColor(RGB(30, 30, 30))
;- Skybox
SkyBox("stevecube.jpg")
Repeat
Screen3DEvents()
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
KeyX = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Right)
KeyX = #CameraSpeed
Else
KeyX = 0
EndIf
If KeyboardPushed(#PB_Key_Up)
KeyY = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Down)
KeyY = #CameraSpeed
Else
KeyY = 0
EndIf
EndIf
If ExamineMouse()
MouseX = -(MouseDeltaX()/10)
MouseY = -(MouseDeltaY()/10)
EndIf
MoveCamera (0, KeyX, 0, KeyY)
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
; Waves
UpdateMatrix()
AngleVague = AngleVague+WaveFrequency
RenderWorld()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
End
;-Procédures
Procedure Normalize(*V.Vector3)
Protected.f magSq, oneOverMag
magSq = *V\x * *V\x + *V\y * *V\y + *V\z * *V\z
If magsq > 0
oneOverMag = 1.0 / Sqr(magSq)
*V\x * oneOverMag
*V\y * oneOverMag
*V\z * oneOverMag
EndIf
EndProcedure
Procedure NormalFace(*n.Vector3, *v1.Vector3, *v2.Vector3, *v3.Vector3)
Protected.Vector3 v2v1, v3v1
SubVector3(v2v1, *v2, *v1)
SubVector3(v3v1, *v3, *v1)
*n\x = v2v1\y * v3v1\z - v2v1\z * v3v1\y
*n\y = v2v1\z * v3v1\x - v2v1\x * v3v1\z
*n\z = v2v1\x * v3v1\y - v2v1\y * v3v1\x
EndProcedure
Procedure DrawMatrix()
Protected.l a, b, c, Nb
Protected.w P1, P2, P3, P4
For b=0 To #Nbz
For a=0 To #NbX
;les coordonnées de vertex
y.f=Sin(Radian((AngleVague+a*WavePeriodX+b*WavePeriodZ)))*WaveAmplitude
MeshVertexPosition(a - #NbX/2, y, b - #Nbz/2)
MeshVertexNormal(0,1,0)
MeshVertexTextureCoordinate(a/#NbX, b/#Nbz)
Next a
Next b
Nb=#NbX+1
For b=0 To #NbZ-1
For a=0 To #NbX-1
P1=a+(b*Nb)
P2=P1+1
P3=a+(b+1)*Nb
P4=P3+1
MeshFace(P3, P2, P1)
MeshFace(P2, P3, P4)
Next
Next
EndProcedure
Procedure CreateMatrix()
CreateMesh(0, #PB_Mesh_TriangleList, #True)
DrawMatrix()
FinishMesh(#True)
SetMeshMaterial(0, MaterialID(1))
CreateNode(0)
CreateEntity(0, MeshID(0), #PB_Material_None)
ScaleEntity(0, 3, 3, 3)
GetMeshData(0,0, MeshData(), #PB_Mesh_Vertex, 0, MeshVertexCount(0, 0)-1)
GetMeshData(0,0, MeshDataInd(), #PB_Mesh_Face, 0, MeshIndexCount(0, 0)-1)
EndProcedure
Procedure UpdateMatrix()
Protected a, b, c, i, j
Protected N.Vector3, V1.Vector3, V2.Vector3, V3.Vector3
Protected.f magSq, oneOverMag
For b=0 To #Nbz
For a=0 To #NbX
;les coordonnées de vertex
MeshData(c)\y=Sin(Radian((AngleVague+a*WavePeriodX+b*WavePeriodZ)))*WaveAmplitude
;Init les normales
MeshData(c)\NormalX = 0
MeshData(c)\NormalY = 0
MeshData(c)\NormalZ = 0
c + 1
Next a
Next b
;Calcul les normales
For j=0 To ArraySize(MeshDataInd())-2 Step 3
V1\x = MeshData(MeshDataInd(j )\Index)\x
V1\y = MeshData(MeshDataInd(j )\Index)\y
V1\z = MeshData(MeshDataInd(j )\Index)\z
V2\x = MeshData(MeshDataInd(j+1)\Index)\x
V2\y = MeshData(MeshDataInd(j+1)\Index)\y
V2\z = MeshData(MeshDataInd(j+1)\Index)\z
V3\x = MeshData(MeshDataInd(j+2)\Index)\x
V3\y = MeshData(MeshDataInd(j+2)\Index)\y
V3\z = MeshData(MeshDataInd(j+2)\Index)\z
NormalFace(@N, @V1, @V2, @V3)
;Normalize(@N)
MeshData(MeshDataInd(j )\Index)\NormalX + N\x
MeshData(MeshDataInd(j )\Index)\NormalY + N\y
MeshData(MeshDataInd(j )\Index)\NormalZ + N\z
MeshData(MeshDataInd(j+1)\Index)\NormalX + N\x
MeshData(MeshDataInd(j+1)\Index)\NormalY + N\y
MeshData(MeshDataInd(j+1)\Index)\NormalZ + N\z
MeshData(MeshDataInd(j+2)\Index)\NormalX + N\x
MeshData(MeshDataInd(j+2)\Index)\NormalY + N\y
MeshData(MeshDataInd(j+2)\Index)\NormalZ + N\z
Next
For i=0 To ArraySize(MeshData())
magSq = MeshData(i)\NormalX * MeshData(i)\NormalX +
MeshData(i)\NormalY * MeshData(i)\NormalY +
MeshData(i)\NormalZ * MeshData(i)\NormalZ
If magsq > 0
oneOverMag = 1.0 / Sqr(magSq)
MeshData(i)\NormalX * oneOverMag
MeshData(i)\NormalY * oneOverMag
MeshData(i)\NormalZ * oneOverMag
EndIf
Next
SetMeshData(0,0, MeshData(), #PB_Mesh_Vertex | #PB_Mesh_Normal, 0, MeshVertexCount(0, 0)-1)
EndProcedure