Bon en orientant la caméra au début, ça donne un résultat un peu mieux, mais c'est pas encore ça. Je ne sais pas ce que je fais mal, mais c'est mal
Code : Tout sélectionner
IncludePath "Include\"
IncludeFile "d3dx9.pbi"
IncludeFile "dreamotion3d.pbi"
IncludeFile "PhysX.pbi"
Structure s_Vecteur
x.f
y.f
z.f
EndStructure
Structure s_Rayon
;Informations dans R3
Origine.s_Vecteur
Direction.s_Vecteur
;Informations Dans la base de l'ellipsoide
OrigineDansBaseE.s_Vecteur
DirectionDansBaseE.s_Vecteur
;Informations collisions
CollisionDetectee.l
DistanceLaPlusCourte.f
PointIntersection.s_Vecteur
EndStructure
Macro COS_DEG(Angle)
Cos((Angle) * 0.0174533)
EndMacro
Macro SIN_DEG(Angle)
Sin((Angle) * 0.0174533)
EndMacro
Macro TAN_DEG(Angle)
Tan((Angle) * 0.0174533)
EndMacro
Macro NORME(V)
(Sqr(V\x * V\x + V\y * V\y + V\z * V\z))
EndMacro
Global *camera
Global *mesh
Global *Sphere
Global *font
Global *Light1
Global MouseX.f, MouseY.f, CameraAngleX.f, CameraAngleY.f
Global Rayon.s_Rayon
Global *resul.CEntity
Global *sph.CEntity
Global face.l
Global *line.CEntity
Global Dim tri.l(3)
Global Dim v0.f(3), Dim v1.f(3), Dim v2.f(3)
Global mat.D3DXMATRIX
; first init
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
End
EndIf
;-------------------
; 3D engine init
;-------------------
ScreenWidth.l = 800
ScreenHeight.l = 600
ScreenWidth2.f = ScreenWidth/2.0
ScreenHeight2.f = ScreenHeight/2.0
ScreenDepth.l = 32
OpenScreen(ScreenWidth, ScreenHeight, ScreenDepth, "Dreamotion3D...")
DM_InitGraphics(ScreenID(), ScreenDepth, 1, 1)
*DM_d3d9 = DM_GetD3D9()
*DM_d3dDev9 = DM_GetDevice9()
DM_WIDTH = ScreenWidth
DM_HEIGHT = ScreenHeight
SetCurrentDirectory("medias/")
;---------------------------------
; INIT DU MOTEUR PHYSIQUE
;---------------------------------
NX_Init(*DM_d3dDev9)
NX_SetGravity(0.0, -50.0, 0.0)
; Charge une font
*font = DM_LoadFont("Arial",8 , 1)
DM_SetColorText (*font, 198,198,198,255)
;------------------------
; load a B3D file
*mesh = DM_LoadEntity("SacredPlace.b3d", #Null, #False)
NX_CreateStaticElement(*mesh, 10, 0)
*Sphere = DM_CreateSphere()
DM_PositionEntity(*Sphere, 100 + COS_DEG(0) * 1000, 150,100 - SIN_DEG(0) * 1000)
;- camera
*camera = DM_CreateCamera(#Null)
DM_PositionEntity(*camera, 100, 150, 100)
DM_CameraClsColor(*camera, 0, 0, 0)
DM_CameraProjRatio(*camera, 800,600, 6000)
DM_PointEntity(*camera, *Sphere)
NX_CreateCharacter(*camera, 0, 126, 0, 25.0, 150, 0.1)
NX_EntityCollideCallBack(*camera, Collision)
NX_SetCharacterGroup(*camera, 4)
NX_SetSpeedJumpCharacter(*camera, 5.5)
;------------------------------
; une p'tite ligne
;------------------------------
*line = DM_CreateLine(4)
DM_LinePoint(*line, 0,20,10, 0,255,0)
DM_LinePoint(*line, 10,20,0, 0,250,0)
DM_LinePoint(*line, 10,20,10, 0,250,0)
DM_CloseLine(*line)
;-Light
DM_AmbiantLight(80, 80, 80)
*Light1 = DM_CreateLight(1, null)
DM_LightColor(*Light1, 255, 255, 0, 100)
DM_LightAttenuation(*Light1, 2, 2, 2)
Declare.f WrapValue(angle.f)
Declare Normalise(*N.s_Vecteur)
;-----------------------------
; ------- main loop --------
;------------------------------
CameraAngleX = 90
Repeat
ExamineKeyboard()
ExamineMouse()
MouseX = (MouseDeltaX() / 10) * 5 / 3
MouseY = (MouseDeltaY() / 10) * 5 / 3
;MemMouseX + MouseX
CameraAngleX = WrapValue(CameraAngleX + MouseX)
DM_TurnEntity(*camera, 0, MouseX, 0)
If MouseY > 0 And CameraAngleY < 60
CameraAngleY + MouseY
DM_TurnEntity(*camera, MouseY, 0, 0)
ElseIf MouseY < 0 And CameraAngleY > -60
CameraAngleY + MouseY
DM_TurnEntity(*camera, MouseY, 0, 0)
EndIf
If MouseButton(1)
Rayon\Direction\x = COS_DEG(CameraAngleX)
Rayon\Direction\y = TAN_DEG(-CameraAngleY)
Rayon\Direction\z = -SIN_DEG(CameraAngleX)
Normalise(Rayon\Direction)
*resul = NX_RayCastAnyShape(DM_EntityX(*camera), DM_EntityY(*camera), DM_EntityZ(*camera), Rayon\Direction\x, Rayon\Direction\y, Rayon\Direction\z)
;récupère la face trouvée
face = NX_RaycasFaceID()
; récupère les vertex associé
DM_TriangleVertex(*resul, face, @tri(0))
; transpose dans des tableau de vertex pour traitement
v0(0) = DM_VertexX(*resul, tri(0))
v0(1) = DM_VertexY(*resul, tri(0))
v0(2) = DM_VertexZ(*resul, tri(0))
v1(0) = DM_VertexX(*resul, tri(1))
v1(1) = DM_VertexY(*resul, tri(1))
v1(2) = DM_VertexZ(*resul, tri(1))
v2(0) = DM_VertexX(*resul, tri(2))
v2(1) = DM_VertexY(*resul, tri(2))
v2(2) = DM_VertexZ(*resul, tri(2))
; recup la matrice d'attitude du mesh ttrouvé
DM_EntityWorld(*resul, @mat)
; transpose les coordonnées brut des vertices dans le world de représentation du mesh trouvé
D3DXVec3TransformCoord(@v0(0), @v0(0), @mat)
D3DXVec3TransformCoord(@v1(0), @v1(0), @mat)
D3DXVec3TransformCoord(@v2(0), @v2(0), @mat)
; modifie les point du line pour une représentation graphique de la face
DM_LinePosition(*line, 0, v0(0), v0(1), v0(2) )
DM_LinePosition(*line, 1, v1(0), v1(1), v1(2) )
DM_LinePosition(*line, 2, v2(0), v2(1), v2(2) )
DM_LinePosition(*line, 3, v0(0), v0(1), v0(2) )
;Dist.f = NX_RaycasDistance()
;DM_PositionEntity(*Sphere, \Origine\x + Dist * \Direction\x, \Origine\y + Dist * \Direction\y,\Origine\z + Dist * \Direction\z)
EndIf
If KeyboardPushed(#PB_Key_Space)
NX_JumpCharacter(*camera, 350.0)
EndIf
If KeyboardPushed(#PB_Key_Up)
NX_MoveCharacter(*camera, 320.0)
ElseIf KeyboardPushed(#PB_Key_Down)
NX_MoveCharacter(*camera, -320.0)
EndIf
If KeyboardPushed(#PB_Key_Right)
NX_StrafeCharacter(*camera, CameraAngleX+90, 320)
ElseIf KeyboardPushed(#PB_Key_Left)
NX_StrafeCharacter(*camera, CameraAngleX-90, 320)
EndIf
NX_Update()
DM_PositionEntity(*Light1,DM_EntityX(*camera), DM_EntityY(*camera)+ 40, DM_EntityZ(*camera))
DM_BeginScene()
DM_RenderWorld()
DM_DrawText(*font, 0, 0, Str(DM_FPS()))
DM_DrawText(*font, 0, 20, StrF(Rayon\Direction\x,1) + " " + StrF(Rayon\Direction\y,1) + " " + StrF(Rayon\Direction\z,1))
DM_SetColor2D(255, 255, 255, 255)
DM_DrawLine(ScreenWidth2-5,ScreenHeight2-5,ScreenWidth2+6,ScreenHeight2+6)
DM_DrawLine(ScreenWidth2-5,ScreenHeight2+5,ScreenWidth2+6,ScreenHeight2-6)
DM_EndScene()
Until KeyboardPushed(#PB_Key_Escape)
DM_ClearGraphics()
End
Procedure Normalise(*N.s_Vecteur)
Define.f NormeVecteur
NormeVecteur = NORME(*N)
If NormeVecteur <> 0.0
*N\x / NormeVecteur
*N\y / NormeVecteur
*N\z / NormeVecteur
EndIf
EndProcedure
Procedure.f WrapValue(angle.f); <- wraps a value into [0,360) fringe
;Psychophanta : http://purebasic.fr/english/viewtopic.php?t=18635
!fild dword[@f] ; <- now i have 360 into st0
!fld dword[p.v_angle]
!fprem
!fadd st1,st0
!fldz
!fcomip st1
!fcmovnbe st0,st1
!fstp st1
ProcedureReturn
!@@:dd 360
EndProcedure