Page 2 sur 2

The must

Publié : jeu. 05/avr./2007 6:03
par leo.cd
Alors la je tiens une exclusivité :

impossible d'avoir des fonctions ODE et Dreamotion dans une même fonction ^^.

ODE = ProcedureC
Dreamotion = Procedure ( avec C ca fait le même plantage qu'au début )

et comme ProcedureC ne peut appeller que des ProcedureC et vice versa pour Procedure, je ne voit pas trop comment faire ...

Une idée ??


PS : les boules tombent bien et les collisions fonctionne, reste à ce que le sol ne soit pas aussi réactif après collision.

Publié : jeu. 05/avr./2007 14:21
par Flype
j'ai l'intuition que tu t'avances beaucoup là.

car je ne vois où tu as besoin de ProcedureC...

PrototypeC, Ok je vois.
CallCFunction(), Ok je vois.

ProcedureC, non pas besoin en principe.


Un nouveau bout de code, stp ?

Re: Question HS

Publié : jeu. 05/avr./2007 15:15
par Flype
leo.cd a écrit :J'ai une question HS, mais comme j'ai commencé ici je continue :

dans la doc de ode je rencontre souvent le type de variables int, ca corespond à quoi en PureBasic ? et surtout : combien d'octets ca prend ?
voir ici - tuto ajouté ce jour :
http://www.purebasic.fr/french/viewtopic.php?t=6451

Publié : jeu. 05/avr./2007 19:12
par tmyke
Personnelement, je n'aborderais globalement le problème d'une manière légèrement différente.
En fait, je ferais vraiment un wrap de ta librairie (dans ton cas ODE).

J'avais fait le meme genre de chose pour coupler Newton a Dreamotion3D.
(pour toi il suffit de faire pareil avec ODE)


Donc, j'avais placé le fichier 'Newton.lib' dans le rep 'PureLibraries\windows\Libraries'
Ensuite j'ai créé un fichier wrappant les fonctions de la librairie, comme suit:

Code : Tout sélectionner

; fichier Newton.pbi
;
	Structure NewtonBody
	EndStructure
	Structure NewtonWorld
	EndStructure
	Structure NewtonJoint
	EndStructure
	Structure NewtonContact
	EndStructure
	Structure NewtonMaterial
	EndStructure
	Structure NewtonCollision
	EndStructure
; ... etc ....
ImportC "Newton.lib"
;
; world control functions
NewtonCreate.l(*NewtonAllocMemory, *NewtonFreeMemory)
NewtonDestroy(*newtonWorld.NewtonWorld)
NewtonDestroyAllBodies(*newtonWorld.NewtonWorld)
; 
;etc...  avec toutes les fonctions a wrapper

EndImport
et dans mon code PureBasic, j'écrivais:

Code : Tout sélectionner

IncludePath "Include\"

  IncludeFile "dreamotion3d.pbi"
  IncludeFile "Newton.pbi"

... etc ...

; memory allocation For Newton
ProcedureC.l  PhysicsAlloc(sizeInBytes.l)
	ProcedureReturn AllocateMemory(sizeInBytes)
EndProcedure
;memory de-allocation For Newton
ProcedureC PhysicsFree(*ptr, sizeInBytes.l)
	FreeMemory(*ptr)
EndProcedure
ProcedureC PhysicsSetTransform (*body.NewtonBody, *mat)
  Protected *ent.CEntity 
  *ent = NewtonBodyGetUserData(*body)
  DM_WorldEntity(*ent, *mat)
EndProcedure
; intern procedure application
Procedure DrawStat(*entity.CEntity)
   DM_DrawText(*font, 10, 15, Posx : "+StrF(DM_EntityX(*entity)))	
EndProcedure

; init diverses....
;---------------------------------------------
; create the newton world
;---------------------------------------------
*nWorld = NewtonCreate(@PhysicsAlloc(), @PhysicsFree())
etc...
NewtonBodySetTransformCallback (*boxBody, @PhysicsSetTransform())
etc...

La pas de soucis. Cela tournais nickel et sans problème.
Pour les CallBack de Newton, j'employais bien sur des procedure type ProcedureC,
sinon pour le reste de mon appli, je restais bien sur des procedures standards
type 'Procedure'.
Pour ODE il te suffit d'employer le meme mécanisme...

merci

Publié : jeu. 05/avr./2007 20:15
par leo.cd
@ Flype : merci pour le lien, je le lirais plus tard


@ tmyke : merci, je vais essayer de voir ce qui difére de mon code (pas grand chose en fait je crois)

Quelle est la différence entre une lib et une dll ? une lib c'est plus rapide ? pareille ?

EDIT : une lib c'est inclue à l'EXE ou pas ?

Publié : jeu. 05/avr./2007 20:47
par Flype
En fait, il existe 2 types de fichier .lib

1/
Premier cas,
Il s'agit juste d'un petit fichier .lib accompagnant une DLL. Ce fichier n'est utile qu'au programmeur, pas à l'utilisateur final.
Il permet, et c'est très pratique, de charger les fonctions de la DLL dans le source purebasic de manière beaucoup plus naturelle et économique en nombre de lignes qu'avec l'ouverture de la DLL par le classique Open/CloseLibrary(). C'est tellement pratique que lorsqu'une DLL qui m'intéresse n'est pas livré avec ce petit fichier .lib, je boude un peu la DLL.
Dans tous les cas, ce fichier .lib est automatiquement créé par purebasic lorsqu'on créé nous meme une DLL, histoire de faciliter son utilisation par la suite dans purebasic. Ceci dit la DLL est toujours indispensable et doit etre distribuer avec le programme.

par exemple prenons une DLL 'helper.dll' qui contient une fonction box(message.s)

Classiquement on programmera la DLL comme ceci :

Code : Tout sélectionner

Prototype.l proto_box(message.s)

If OpenLibrary(0, "helper.dll")
  box.proto_box = GetFunction(0, "box")
  CloseLibrary(0)
EndIf
Si on a la chance d'avoir le fichier .lib, c'est beaucoup plus pratique (à mon avis) comme ceci :

Code : Tout sélectionner

Import "helper.lib" ; à noter le .lib au lieu .dll
  box.l(message.s)
EndImport
Ou bien si on veut renommer la fonction à notre convenance :

Code : Tout sélectionner

Import "helper.lib" ; à noter le .lib au lieu .dll
  dialogue.l(message.s) As "box@4" ; 4 est le nombre d'octets occupés par l'ensemble des arguments (4 pour 1 Long)
EndImport
2/
Deuxieme cas,
Le fichier .lib est une sorte de DLL (D comme Dynamic) mais cette fois cette lib est un fichier Static ou toutes les fonctions sont DANS le fichier .lib (qui pour le coup est beaucoup plus gros que dans le 1er cas).
Donc ici plus besoin de DLL, le .lib est intégré dans l'exécutable, caché de l'utilisateur final. Très pratique aussi.
Dans la pratique, çà se programme comme dans le 1er cas.


Les 2 cas sont exploitables avec PureBasic.
J'ai déjà utiliser les 2 avec succès mais cela ne fonctionne pas à tous les coup. Ca dépends comment a été compilé le fichier .lib
Querstion vitesse, çà ne change rien en principe que ce soit pour une DLL, une LIB de linkage (1er cas) ou une LIB statique (2eme cas).

Publié : jeu. 05/avr./2007 20:54
par leo.cd
merci pour tes précisions.

Bin voila que je me rend compte qu'avec ode j'avais les 2 types de lib ^^. et je n'ai profité d'aucune. 1500 lignes dans le vent ... Menfin faut bien passer par là pour apprendre.

Pour le deuxième type de lib ( inclue à l'EXE et sans dll ) c'est plus rapide qu'une dll ? moins rapide ? équivalent ?

Publié : jeu. 05/avr./2007 20:59
par Flype
A priori - je peux me tromper - ce devrait être équivalent.

En effet, dans tous les cas, le bloc de codes que représente la lib est chargée en mémoire.
Chaque fonction n'est rien d'autre qu'un pointeur en mémoire quelque soit sa forme.

[EDIT]
Ce qui sera plus lent, dans la pratique, c'est quand tu feras de l'encapsulation.
C'est à dire si tu reprends une fonction d'une lib pour l'englober dans une procédure pour en faciliter son utilisation. Là, concrètement, il se passera un double appel en mémoire (Appel à ta procédure et l'interprétation de ses arguments qui ajoute un empilement/dépilement supplémentaire à gérer par le processeur PUIS l'appel à la vraie fonction qui elle même doit traitée ses arguments etc...)

problème avec les listes chainées

Publié : jeu. 05/avr./2007 21:34
par leo.cd
l'explication doit être une fois de plus assez simple mais j'ai un pb avec une liste chainée :

Code : Tout sélectionner

Structure obj

  pos.v3d
  angle.v3d
  
  odeId.l
  odeGId.l
  *dm

EndStructure

Structure listObj

  *obj.obj
  active.b

EndStructure

Global NewList listObjet.listObj()
Global tp_mass.mass

; ---------------------------------------
;          Fonctions de création d'un objet
; ---------------------------------------

Procedure makeClassicObj(*objet.obj, *brush, x.f, y.f, z.f, rayon.f, active.b)

  DM_ScaleMesh(*objet\dm, rayon*2, rayon*2, rayon*2)
  DM_PaintMesh(*objet\dm, *brush)

  *objet\odeId = ode_dBodyCreate(idW)
  ode_dBodySetPosition(*objet\odeId, x, y, z)
  
  ode_dGeomSetBody(*objet\odeGId, *objet\odeId)
  
  ode_dBodySetMass(*objet\odeId, @tp_mass)
  
  
  ; liste des objet
  
  AddElement(listObjet())
  
  listObjet()\obj = *objet
  listObjet()\active = active

EndProcedure


Procedure makeObjBall(*objet.obj, *brush, x.f, y.f, z.f, masse.f, rayon.f, active.b = 1)

  *objet\dm = DM_CreateSphere()
  *objet\odeGId = ode_dCreateSphere(idS, rayon*3)
  ode_dMassSetSphereTotal(@tp_mass, masse, rayon*3)
  
  makeClassicObj(*objet, *brush, x, y, z, rayon, active)

EndProcedure

; ---------------------------------------
;          Création des objets
; ---------------------------------------

*texture = DM_LoadTexture("texture.jpg")
*brush = DM_CreateBrush.l("boule")
DM_BrushTexture(*brush, *texture)

ball1.obj

makeObjBall(@ball1, *brush, -1, 200, -3, 60, 1)
mon problème est le suivant :
LinkedList not initialized
pour la ligne

Code : Tout sélectionner

AddElement(listObjet())
dsl d'enchaînner problème sur problème ...

J'ai le même problème avec une autre fonction et une autre liste chaînée mias dans ce cas en fonction de l'emplacement de la création de la liste (toujours avant la fonction) soit la fonction ne peut pas lire la liste, soit ma boucle principale.

( J'aurais du poster dans la forum débutant ? )