Page 15 sur 62

Publié : dim. 05/nov./2006 20:54
par tmyke
D'abord quand tu place ta camera puis en suite tu cree le NxCharacter, donne les meme positons.
Sinon, cela crée un conflit entre le moteur physique et le moteur graphique

Code : Tout sélectionner

DM_PositionEntity(*camera, 0, 126, 0)
...
NX_CreateCharacter(*camera, 0, 126, 0, 25.0, 150, 0.1)
Faudra que je créé un lien interne pour basculer les position physique vers celle graphique.

En suite j'ai juste fait :

Code : Tout sélectionner

Rayon\Direction\x = Sin( DM_EntityPitch(*camera) * 0.01745)
Rayon\Direction\y = 0
Rayon\Direction\z = Cos( DM_EntityPitch(*camera) * 0.01745)
Cela ne donne que les position verticale, mais dès lors cela fonctionne très bien, pas besoin de
normaliser car la routine RayCast le fait déjà pour toi. A toi d'ajouter l'autre angle (Yaw) pour mixer et
avoir dans les trois dimension. Attiention les angles retournés par DM3D sont toujours en Degrés.
Par contre la camera se retrouve de base orientée vers le bas, faut que je vois pourquoi...

En suite, dernier conseil, ne cree pas un NXCharacter sur une Entity camera, mais plustot sur une
entity réél, comme un cube, auquel tu met en child la camera...
Cela évitera les effets indésirable de positionnement de la camera, car
le moteur physique prend toujours le pas sur les instruction graphiques
(NX -> DM)
Image

Publié : dim. 05/nov./2006 20:56
par tmyke
voila l'ensemble... demain je reprend, et j'te finis cela :wink:

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 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, 20, 20, 0)
	
;- camera
*camera = DM_CreateCamera(#Null)
DM_PositionEntity(*camera, 0, 126, 0)
DM_RotateEntity(*camera, 0,0,90)
DM_CameraClsColor(*camera, 0, 0, 0)
DM_CameraProjRatio(*camera, 800,600, 5000)
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) 
  
  
Declare.f WrapValue(angle.f)
Declare Normalise(*N.s_Vecteur)



;-----------------------------
; ------- main loop --------
;------------------------------
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 = Sin( DM_EntityPitch(*camera) * 0.01745)
			Rayon\Direction\y = 0
			Rayon\Direction\z = Cos( DM_EntityPitch(*camera) * 0.01745)
			
			;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)
	EndIf
	If KeyboardPushed(#PB_Key_Down) 
	  NX_MoveCharacter(*camera, -320.0)
	EndIf
	If KeyboardPushed(#PB_Key_Right) 
	  NX_TurnCharacter(*camera, 1.0)
	  angle = angle + 1.0
	EndIf
	If KeyboardPushed(#PB_Key_Left) 
	  NX_TurnCharacter(*camera, -1.0)
	  angle = angle -1.0
	EndIf
	If KeyboardPushed(#PB_Key_T) 
	  NX_StrafeCharacter(*camera, angle+90, 100)
	EndIf
	If KeyboardPushed(#PB_Key_R) 
	  NX_StrafeCharacter(*camera, angle-90, 100)
	EndIf
	
  NX_Update()
  DM_BeginScene()
    DM_RenderWorld()
    DM_DrawText(*font, 0, 0, Str(DM_EntityPitch(*camera)));Str(CameraAngleY))
    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

Publié : dim. 05/nov./2006 21:12
par comtois
C'est bizarre la caméra est bloquée vers le bas dans ton code, mais pas dans le mien ?

Bon ok, j'ai appris des trucs au passage
pas la peine de normer
Utiliser une entity plutôt que la caméra

Mais en reprenant tes conseils, ça fonctionne mieux, mais pas toujours, si je me déplace, il y a un décalage entre la croix et le triangle affiché.

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 
Global matcam.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, 100, 150, 100, 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,  155,  0, 100)
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)
      DM_EntityWorld(*camera, @matcam) 
      Rayon\Direction\x = Sin( DM_EntityPitch(*camera) * 0.01745)
      Rayon\Direction\y = 0
      Rayon\Direction\z = Cos( DM_EntityPitch(*camera) * 0.01745) 

			;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)
      ;*resul = NX_RayCastAnyShape(DM_EntityX(*camera), DM_EntityY(*camera), DM_EntityZ(*camera), matcam\_31, matcam\_32, matcam\_33)
          ;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(matcam\_31,1) + " " + StrF(matcam\_32,1) + " " + StrF(matcam\_33,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
[EDIT]
Faudra que je créé un lien interne pour basculer les position physique vers celle graphique.
Ben oui sinon je suppose que dès que je bouge DM_EntityPitch(*camera) me renvoie n'importe quoi ,ça ne correspond plus à rien ?

Publié : lun. 06/nov./2006 7:04
par tmyke
Je m'y recolle en rentrant du boulot, il s'agit d'un probleme d'interférence entre
les instructions de controle des entity entre DM3D et PhysX. En quelque sorte
un bug...

Publié : lun. 06/nov./2006 9:58
par Progi1984
Là, les bugs arrivent ... et le codeur répare :)

Bon boulot et bonne réaction de TMyke...

Publié : lun. 06/nov./2006 10:33
par tmyke
En fait, si tu places la routine de calcul des RayCast après le NX_Update(), la
mise a jour des positions de l'entity est bonne (normal), et la cela semble très nettement mieux fonctionner

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
Global matcam.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, 100, 150, 100, 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,  155,  0, 100)
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 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()

  ;If MouseButton(1)
      DM_EntityWorld(*camera, @matcam)
      Rayon\Direction\x = Sin( DM_EntityPitch(*camera) * 0.01745)
      Rayon\Direction\y = 0
      Rayon\Direction\z = Cos( DM_EntityPitch(*camera) * 0.01745)
                       
      *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) )
     
  ;EndIf
  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, Str(DM_EntityX(*camera)) + " " + Str(DM_EntityY(*camera)) + " " + Str(DM_EntityZ(*camera)) + " " + Str(DM_EntityPitch(*camera)));matcam\_33,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

Publié : lun. 06/nov./2006 13:15
par comtois
C'est déjà beaucoup mieux :)

Je vais arranger le code, et ajouter la dernière composante du vecteur directeur.

Par contre tu n'as pas un truc pour améliorer les collisions ? pour éviter de grimper les murs ?

Regarde les murs inclinés de chaque côté du porche, on monte dessus.

Il me reste à ajouter les faisceaux et j'aurai reconduit l'exemple dans ma signature avec ton moteur en beaucoup moins de lignes :)

[EDIT]

C'est bon , j'ai réussi à gérer le vecteur directeur.

J'ai repris l'idée que j'avais en tête, en utilisant la matrice de la caméra :)
DM_EntityWorld(*camera, @matcam)
*resul = NX_RayCastAnyShape(DM_EntityX(*camera), DM_EntityY(*camera), DM_EntityZ(*camera), matcam\_31, matcam\_32, matcam\_33)

Il me reste à calculer le point d'intersection.

[EDIT2]
Ok le calcul des distances fonctionne, j'ai fait comme ça
Dist.f = NX_RaycasDistance()
DM_PositionEntity(*Sphere,DM_EntityX(*camera) + matcam\_31 * Dist, DM_EntityY(*camera) + matcam\_32 * Dist, DM_EntityZ(*camera) + matcam\_33 * Dist)

Je mets la sphère à l'intersection pour vérifier le calcul.

A tout hasard, tu as une autre méthode ou c'est la bonne ?

Bon j'y suis bientôt, les faisceaux ne devraient pas poser de problème, j'ai déjà fait un drapeau flottant, je connais les commandes qui vont bien :)

[EDIT3]

J'ai remanié un peu le code.

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_PointF
  x.f
  y.f
EndStructure
  
Global *camera, *mesh, *Sphere, *font, *particule, *line, *Light1
Global Mouse.s_PointF
Define *resul, *sph, face.l
Global mat.D3DXMATRIX, matcam.D3DXMATRIX 
Define.PARTICLE 	ParticuleEmitter
Global ShowTriangle, ShowSphere

Dim triangle.l(2)
Dim Vertex.s_Vecteur(2)
  
Macro COS_DEG(Angle) 
	Cos((Angle) * 0.0174533) 
EndMacro

Macro SIN_DEG(Angle) 
  Sin((Angle) * 0.0174533) 
EndMacro
  
;  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, -40.0, 0.0)

;-Charge une font
*font = DM_LoadFont("Arial", 8, 1)
DM_SetColorText(*font, 255, 255, 0,255)

;-load a B3D file
*mesh = DM_LoadEntity("SacredPlace.b3d", #Null, #False)
NX_CreateStaticElement(*mesh, 10, 0)

;-Sphere
*Sphere = DM_CreateSphere()
DM_ScaleEntity(*Sphere, 4, 4, 4)
ShowSphere = 1
   
;- Particule
; création et alimentation d'une Structure particle
With ParticuleEmitter
  \Yaw               = 90
  \YawVariation      = 10
  \Pitch             = 90
  \PitchVariation    = 10
  \Size              = 5
  \SizeVariation     = 0.15
  \Speed             = 3.0
  \SpeedVariation    = 1.0
  \Lifetime          = 5
  \LifetimeVariation = 5.0
  \gravity           = 9.8
  \interval          = 0
  \StartColorR       = 255
  \StartColorG       = 255
  \StartColorB       = 255
  \EndColorR         = 0
  \EndColorG         = 0
  \EndColorB         = 255
EndWith
; Emetteur 1
*particule = DM_EntityParticle("particle.bmp", 128, *Sphere)
DM_ParticleParams(*particule, @ParticuleEmitter)
DM_ParticleBLEND(*particule, #D3DBLEND_ONE , #D3DBLEND_ONE)
      
;-camera
*camera = DM_CreateCamera(#Null)
DM_CameraClsColor(*camera, 0, 0, 0)
DM_PositionEntity(*camera, 100, 150, 100)
DM_CameraProjRatio(*camera, 800,600, 6000)

NX_CreateCharacter(*camera, 100, 150, 100, 25.0, 150, 0.1)
NX_EntityCollideCallBack(*camera, Collision)
NX_SetCharacterGroup(*camera, 4)
NX_SetSpeedJumpCharacter(*camera, 5.5)
DM_TurnEntity(*camera, 0, 0, 0)

;-une p'tite ligne
*line = DM_CreateLine(4)
DM_LinePoint(*line,  0, 20, 10, 0, 0, 255)
DM_LinePoint(*line, 10, 20,  0, 0, 0, 255)
DM_LinePoint(*line, 10, 20, 10, 0, 0, 255)
DM_CloseLine(*line)

;-Light
DM_AmbiantLight(230,  230,  255)

Declare GestionClavierSouris()

; **************************
; **       main loop      **
; **************************

Repeat
  
  GestionClavierSouris()
  
  NX_Update()

  If MouseButton(1)
      DM_EntityWorld(*camera, @matcam)
      *resul = NX_RayCastAnyShape(DM_EntityX(*camera), DM_EntityY(*camera), DM_EntityZ(*camera), matcam\_31, matcam\_32, matcam\_33)
      Dist.f = NX_RaycasDistance()
      DM_PositionEntity(*Sphere,DM_EntityX(*camera) + matcam\_31 * Dist, DM_EntityY(*camera) + matcam\_32 * Dist, DM_EntityZ(*camera) + matcam\_33 * Dist)
      DM_EntityVisible(*Sphere, ShowSphere)

      If ShowTriangle
        ;récupère la face trouvée
        face = NX_RaycasFaceID()
   
        ; récupère les vertex associé
        DM_TriangleVertex(*resul, face, triangle())
   
        ;récupère la matrice d'attitude du mesh trouvé
        DM_EntityWorld(*resul, @mat)
       
        ;transpose dans des tableaux de vertices pour traitement
        For i = 0 To 2
          Vertex(i)\x = DM_VertexX(*resul, triangle(i))
          Vertex(i)\y = DM_VertexY(*resul, triangle(i))
          Vertex(i)\z = DM_VertexZ(*resul, triangle(i))
          ;transpose les coordonnées brutes des vertices dans le world de représentation du mesh trouvé
          D3DXVec3TransformCoord(@Vertex(i), @Vertex(i), @mat)
          ; modifie les point du line pour une représentation graphique de la face     
          DM_LinePosition(*line, i, Vertex(i)\x, Vertex(i)\y, Vertex(i)\z)      
        Next i
        DM_LinePosition(*line, 3, Vertex(0)\x, Vertex(0)\y, Vertex(0)\z)
      Else
        ;Expédie les lignes en dehors de la scène 3D ( il y a une autre méthode pour cacher des lignes ?)
        For i = 0 To 3
          DM_LinePosition(*line, i, 0, -1000, 0)      
        Next i
    
      EndIf
  EndIf

  DM_BeginScene()
    DM_RenderWorld()
    DM_DrawText(*font, 0,  0, Str(DM_FPS()))
    DM_DrawText(*font, 0, 20, "[F1] 'Cache / Montre' le triangle touche par le tir") 
    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 GestionClavierSouris()
  ExamineMouse()
  Mouse\y = (MouseDeltaX() / 10) * 5 / 3   
  Mouse\x = (MouseDeltaY() / 10) * 5 / 3

  DM_TurnEntity(*camera, 0, Mouse\y, 0)
  If Mouse\x > 0 And DM_EntityYaw(*camera) < 60
    DM_TurnEntity(*camera, Mouse\x, 0, 0)
  ElseIf Mouse\x < 0 And DM_EntityYaw(*camera) > -60
    DM_TurnEntity(*camera, Mouse\x, 0, 0)
  EndIf
  
  ExamineKeyboard()     
  If KeyboardReleased(#PB_Key_F1)
    ShowTriangle = 1 - ShowTriangle
  EndIf
  If KeyboardReleased(#PB_Key_F2)
    ShowSphere = 1 - ShowSphere
  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, DM_EntityPitch(*camera) + 90, 320)
  ElseIf KeyboardPushed(#PB_Key_Left)
    NX_StrafeCharacter(*camera, DM_EntityPitch(*camera) - 90, 320)
  EndIf
EndProcedure

Publié : lun. 06/nov./2006 14:10
par tmyke
[EDIT2]
Ok le calcul des distances fonctionne, j'ai fait comme ça
Citation:
Dist.f = NX_RaycasDistance()
DM_PositionEntity(*Sphere,DM_EntityX(*camera) + matcam\_31 * Dist, DM_EntityY(*camera) + matcam\_32 * Dist, DM_EntityZ(*camera) + matcam\_33 * Dist)


Je mets à la sphère à l'intersection pour vérifier le calcul.

A tout hasard, tu as une autre méthode ou c'est la bonne ?
J'avoue ne pas m'etre penchez sur le prob, mais ta méthode fonctionne
très bien, je me suis baladé dans la scene sans jamais la mettre en défaut... en passant cela tourne a 740 fps sur ma becanne, donc l'opti parait
très bonne... :)

Pour la sensibilité sur les mur incliné, je vais voir, il y a un reglage dans
mes fonctions 'Character' et je te tien au courant

Publié : lun. 06/nov./2006 19:32
par comtois
J'ai ajouté des particules au point d'impact, ça fonctionne très bien.
J'ai aussi voulu ajouter un texte pour indiquer que la touche [F1] permettait de cacher ou montrer le triangle touché par le tir. Mais l'accent ne passe pas ?

Note : j'ai édité le code dans le post plus haut, c'est le dernier à jour.

Publié : lun. 06/nov./2006 19:46
par tmyke
Vraiment trop bon. Pour l 'é', apparement, la fonction des sortie de texte ne
supporte pas les caractère accentués. Encore une petit truc a voir si je peux faire
quelque chose...
:)

Publié : lun. 06/nov./2006 21:54
par bebou007
salut j'ai entandu sur le forum de darkbasic qu'un nouveau moteur pour pure etais en construction donc je suis aller voir se qui en etais et j'ai etais tres impressionner par se moteur etant posseur de playbasic n'etant pas dotter de moteur 3d juste 2d je voulais savoir si les parametre de fonction utiliser dans pure etais les meme que dans la dll ou alors il y a des parametre suplementaire.

j'aimerai si sa vous derange pas avoir le code source de la lib pour pourvoir transphere se moteur sur playbasic merci

Publié : lun. 06/nov./2006 22:13
par comtois
j'ai testé avec un autre décors issu de deled , WaterWorld

ça fonctionne bien, sauf une pièce qui apparait en rouge dans l'éditeur et pas avec Dreamotion3D.(il faut calculer les lightmap pour voir la pièce rouge)

C'est l'exporter B3D de deled qui déconne , ou l'importer B3D de dreamotion3D ?

Publié : lun. 06/nov./2006 22:29
par comtois
J'ai un invalid memory access avec la commande NX_RayCastAnyShape()
si le rayon pointe en dehors du décor (s'il y a un trou dans le décor)

Pour repérer un trou, tu peux changer la couleur de la caméra
DM_CameraClsColor(*camera, 255, 0, 255)
Tu n'as plus qu'à viser cette couleur , et pouf !!

Publié : mar. 07/nov./2006 7:57
par Anonyme
je viens de faire joujou avec l'exemple de Comtois, j'ai rajouté 2 3 trucs comme le brouillard, un effet de zoom avec la commande DM_CameraZoom()
Mais lorsque je zoom sur les particules , elles sont plus petites.

Code : Tout sélectionner

If MouseButton(#PB_MouseButton_Right)=1
  zoom = 100
  EndIf
  
  If MouseButton(#PB_MouseButton_Right)=0
  zoom = 120
  EndIf
  
   DM_CameraZoom(*camera,zoom)
Vivement les Shadows, c'est tout ce qui m'manque à moua :D et j'attaque un p'tit projet 3D :D

@++

Publié : mar. 07/nov./2006 13:12
par Anonyme
Voila l'exemple de comtois , mais avec le PurePatator dans les mains ^^
avec aussi du brouillard. (vivement les shadows :D)
C'était juste pour des essais perso entre Dreamotion3D & le format .X animé

File:1->WaterWorldPurePatator.rar
Image


@Tmyke

Sera t'il possible, qu'un mesh en l'occurence l'arme, ne soit pas sujet à la lumière ambiente ?
Si je ne fait pas de ScaleEntity() mon arme passe à travers les murs, sera t'il possible de désactiver le clipping temporairement ?
J'ai pas encore cherché, mais , les skybox seront elles gérer en natif par D3D ?

En tout cas, j'adore D3D :D !

j'oublias, Comment as tu generer la texture de l'exemple du terrain ? y a t'il des logiciel gratos à conseiller pour generer se genre de chose ?
Tu devrais faire un sujet sur ton site avec des liens interessants comme des editeurs de niveaux qui fonctionne avec D3D, ou un generateur terrain,etc...

@++