LECTEUR DE FICHIER MS3D ASCII

shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007 - 25 avril 2007 à 13:36
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007 - 29 avril 2007 à 13:04
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/42436-lecteur-de-fichier-ms3d-ascii

shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
29 avril 2007 à 13:04
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
27 avril 2007 à 22:04
bon g modifié la partie rendu et optimisé un peu tous ca
et aussi viré le timer pour tester le fps sans timer car tu bloque le rendu a 50 ms
donc tes fps veulent rien dire (c corrigé pour la prochaire release)
pour le pb des triangles manquants en wireframe g trouvé aussi lol
tu connais pas :
If RFillaire = False Then
PDevice.SetRenderState D3DRS_FILLMODE, D3DFILL_SOLID 'rendu solide
Else
PDevice.SetRenderState D3DRS_FILLMODE, D3DFILL_WIREFRAME 'rendu fils de fer
End If

et non pas
PDevice.DrawPrimitiveUP D3DPT_LINELIST, 1, Model3d(i).Vertices(0), Len(Model3d(i).Vertices(0))
le 1 peut etre remplacé par Model3d(i).nbtris ce qui permet en un appel de faire le rendu de N triangles au lieu de faire N appels de 1 triangle (en gros c plus rapide a l'execution)

et evite aussi au maximum les appels a settexture et setmaterial dans des boucles imbriquées

en gros il faut le faire avant puis balancer le buffer de points en liste (trianglelist)
comme suit :
si pas de texture alors
PDevice.SetTexture 0, Nothing
sinon
PDevice.SetTexture 0, texture
fin si

si material alors
PDevice.SetMaterial Pcouleur
sinon
PDevice.SetMaterial Nothing
fin si

'puis balancer les triangles
For i = 0 To Ms3dFile.NbrMesh - 1
'On dit qu'aucune texture ne sera affichée
PDevice.DrawPrimitiveUP D3DPT_TRIANGLELIST, Model3d(i).nbtris, Model3d(i).Vertices(0), Len(Model3d(i).Vertices(0))
Next i
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
27 avril 2007 à 20:15
Les animations en binaire c'est le même principe, je me rapelle avoir eu un resultat similaire à celui de cette source (avant tes apports), mais j'ai bugger le code :s

Amuse toi bien.
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
27 avril 2007 à 20:09
hum je me demande si je devrais pas passer au format binaire des ms3d plus tot parceque le format ascii ... ca ** du *** :op
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
27 avril 2007 à 20:07
ben l'interet de pouvoir charger des ms3d animés c'est qu'on peut creer un format3d perso qui supporte soit les frames soit les bones (donc faire de l'import ou de l'export de mesh vers d'autres formats)
donc si tu utilise un moteur basé sur les keyframes comme quake 2 tu peut alors le modeler et l'animer sous ms3d, puis l'exporter vers ton format 3d perso pour un jeu ou autre...
ou alors faire un editeur d'animations plus sympas que celui de ms3d comme copier/coller des keyframes pour organiser les animations ou encore avoir les animations dans des fichiers externes au model etc ...

donc oui je pense que je vais la modifier (si j'ai le temps lol)
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
27 avril 2007 à 19:36
Corrige tout ce que tu veux, je ne comptais plus modifier cette source mais si tu apportes des ameliorations je t'en pris ^^.
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
27 avril 2007 à 19:33
nan ton loader etait bon mais trop long :op
ma methode est plus "normale" et evite de creer des chaines,des tableaux , des replaces etc ...

bon g recoder pas mal de truc et les anims fonctionnents nickel

mais y a deux bugs encore :
- effet miroir de la scene sur l'axe x (en gros le perso est inversé sur x ainsi que l'anim)
- des triangles sont manquants lors du rendu 3d donc ca fait pas bo :op

je les corriges ou pas ?? :o)
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
27 avril 2007 à 16:25
Chez moi ton module change rien...
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
27 avril 2007 à 13:44
Public Function SubString$(Value$, a$, b$)
Dim istart As Long, istop As Long

istart = InStr(UCase$(Value$), UCase$(a$)) + Len(a$)
istop = InStr(istart, UCase$(Value$), UCase$(b$))
If istop > istart Then
SubString$ = Mid$(Value$, istart, istop - istart)
Else
SubString$ = ""
End If
End Function
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
26 avril 2007 à 19:47
Manque un morceau apparement, SubString non definie ^^.
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
26 avril 2007 à 19:21
'le new module MloadMs3d.bas cc Dre@mSoft 2007 by ShadowMoy:

Option Explicit

Public Type ms3D_vertex
Drapeau As Long
coordonée As D3DVECTOR
uv(1) As Single
Index As Long
End Type

Public Type ms3d_Triangle
Drapeau As Long
Indices(2) As Single
NormalIndices(2) As Single
Index As Long
End Type

Private Type ARGBcolor
alpha As Single
Red As Single
Green As Single
Blue As Single
End Type

Public Type ms3d_material
Nom As String
Ambient As ARGBcolor
diffus As ARGBcolor
Speculaire As ARGBcolor
Emetteur As ARGBcolor
Brillant As Single
Transparence As Single
DiffuseTexture As String
AlphaTexture As String
End Type

Public Type ms3d_framecle_rot
Durée As Single 'Temps en seconde
Rotation As D3DVECTOR 'X,Y,Z de l'angle
End Type

Public Type ms3d_framecle_pos
Durée As Single 'Temps en seconde
Position As D3DVECTOR 'Position locale
End Type

Public Type ms3d_Struct
Flag As Byte 'durée ' Sélectionné ou non,visible ou non etc ...
Nom As String '32
NomParent As String
ParentIndex As Integer
Rotation As D3DVECTOR 'Translation
Position As D3DVECTOR
mRelative As D3DMATRIX
mAbsolute As D3DMATRIX
mRelativeFinal As D3DMATRIX
mFinal As D3DMATRIX
NbrFrameCléRotation As Long
NbrFrameCléPosition As Long
FrameCleRotation() As ms3d_framecle_rot
FrameClePosition() As ms3d_framecle_pos
End Type

Public Type ms3d_group 'Mesh
Flag As Byte 'Selectionné/caché
Name As String '32 max
NbTriangle As Long
TriangleIndices() As Long
MaterialIndex As Byte '-1 pas de materiel
End Type

Public Type Ms3d_Mesh
Flag As Long
MeshName As String '32 max
NbrVertices As Long
Vertices() As ms3D_vertex
NbrTriangles As Long
Triangles() As ms3d_Triangle
NbrNormal As Long
Normal() As D3DVECTOR
MaterialIndex As Long
End Type

Public Type MS3D
Entete As String ' 256 max
NbrFrames As Long
NbrMesh As Long
Mesh() As Ms3d_Mesh
NbrMateriaux As Long
Materiaux() As ms3d_material
NbrStructure As Long
Structure() As ms3d_Struct
End Type

Public FPS As Single
Public FrameActuelle As Single
Public NbrFrame As Long
Public Ms3dFile As MS3D
Public f As Integer
Public Templong As Long
Public TempInteger As Integer
Public TempString As String
Public TempChar As String
Public TempByte As Byte

Public Sub ReadMs3d()
On Error GoTo fin

Dim I As Long, j As Long
Dim a As String
Dim tp
f = FreeFile

Open (Form1.CommonDialog1.FileName) For Input As f
' Ouvre le fichier et le charge dans une variable tampon de type texte
a = Input$(LOF(f), f)
Close #f

'on recupere le nombre de clés d'animations
Ms3dFile.NbrFrames = SubString(a, "Frames: ", vbCrLf)
NbrFrame = Ms3dFile.NbrFrames
CurrFrame = 1
'on recupere le nombre de groupes (sous objects) du model
Ms3dFile.NbrMesh = SubString(a, "Meshes: ", vbCrLf)

'on redimensionne le tableau de groupes
ReDim Ms3dFile.Mesh(Ms3dFile.NbrMesh - 1)

'on recupere le nombre de materiaux du model
Ms3dFile.NbrMateriaux = SubString(a, "Materials: ", vbCrLf)


'on recupere le nombre de Bones (os du squelette) du model
Ms3dFile.NbrStructure = SubString(a, "Bones: ", vbCrLf)

Open (Form1.CommonDialog1.FileName) For Binary As f

Input #f, Ms3dFile.Entete
If Mid(Ms3dFile.Entete, 1, 2) <> "//" Then
MsgBox ("Ce fichier n'est pas n'est pas à la norme ms3d version Ascii")
GoTo fin
End If


For I = 0 To 4 'skip the 5 first lines
Line Input #f, TempString
Next

'###########################################
'## on commence par recuperer les groupes ##
'###########################################

For I = 0 To Ms3dFile.NbrMesh - 1
'recuperer le nom,le flag et le matindex
Input #f, Ms3dFile.Mesh(I).MeshName, Ms3dFile.Mesh(I).Flag, Ms3dFile.Mesh(I).MaterialIndex


'******************************************************************************************
'************************* recuperation les vertex (points 3D) ****************************
'******************************************************************************************
'on recupere le nombre de points
Input #f, Ms3dFile.Mesh(I).NbrVertices


'on redimensionne le tableau de vertex
ReDim Ms3dFile.Mesh(I).Vertices(Ms3dFile.Mesh(I).NbrVertices - 1)

'recuperer les vertices
For j = 0 To Ms3dFile.Mesh(I).NbrVertices - 1
Input #f, Ms3dFile.Mesh(I).Vertices(j).Drapeau, Ms3dFile.Mesh(I).Vertices(j).coordonée.x, Ms3dFile.Mesh(I).Vertices(j).coordonée.y, Ms3dFile.Mesh(I).Vertices(j).coordonée.z, Ms3dFile.Mesh(I).Vertices(j).uv(0), Ms3dFile.Mesh(I).Vertices(j).uv(1), Ms3dFile.Mesh(I).Vertices(j).Index

Next j

'******************************************************************************************
'************************* recuperation des normales **************************************
'******************************************************************************************

'on recupere le nombre de normales
Input #f, Ms3dFile.Mesh(I).NbrNormal


'on redimensionne le tableau de normales
ReDim Ms3dFile.Mesh(I).Normal(Ms3dFile.Mesh(I).NbrNormal - 1)

'recuperation des normales
For j = 0 To Ms3dFile.Mesh(I).NbrNormal - 1
Input #f, Ms3dFile.Mesh(I).Normal(j).x, Ms3dFile.Mesh(I).Normal(j).y, Ms3dFile.Mesh(I).Normal(j).z
Next j

'******************************************************************************************
'************************* recuperation des triangles *************************************
'******************************************************************************************

'on recupere le nombre de triangles
Input #f, Ms3dFile.Mesh(I).NbrTriangles

'redimensionner le tableau de triangles
ReDim Ms3dFile.Mesh(I).Triangles(Ms3dFile.Mesh(I).NbrTriangles - 1)

'recuperation des triangles
For j = 0 To Ms3dFile.Mesh(I).NbrTriangles - 1
Input #f, Ms3dFile.Mesh(I).Triangles(j).Drapeau, Ms3dFile.Mesh(I).Triangles(j).Indices(0), Ms3dFile.Mesh(I).Triangles(j).Indices(1), Ms3dFile.Mesh(I).Triangles(j).Indices(2), Ms3dFile.Mesh(I).Triangles(j).NormalIndices(0), Ms3dFile.Mesh(I).Triangles(j).NormalIndices(1), Ms3dFile.Mesh(I).Triangles(j).NormalIndices(2), Ms3dFile.Mesh(I).Triangles(j).Index
Next j
Next I

'on recup la ligne vide pour positionner le pointeur sur la ligne vide
Input #f, TempString

'###########################################
'## on recupere ensuite les materiaux ##
'###########################################
Input #f, TempString

If Ms3dFile.NbrMateriaux > 0 Then

ReDim Ms3dFile.Materiaux(Ms3dFile.NbrMateriaux - 1)

For I = 0 To Ms3dFile.NbrMateriaux - 1

'nom
Input #f, Ms3dFile.Materiaux(I).Nom

'Ambient
Input #f, Ms3dFile.Materiaux(I).Ambient.alpha, Ms3dFile.Materiaux(I).Ambient.Red, Ms3dFile.Materiaux(I).Ambient.Green, Ms3dFile.Materiaux(I).Ambient.Blue

'Diffus
Input #f, Ms3dFile.Materiaux(I).diffus.alpha, Ms3dFile.Materiaux(I).diffus.Red, Ms3dFile.Materiaux(I).diffus.Green, Ms3dFile.Materiaux(I).diffus.Blue

'Speculaire
Input #f, Ms3dFile.Materiaux(I).Speculaire.alpha, Ms3dFile.Materiaux(I).Speculaire.Red, Ms3dFile.Materiaux(I).Speculaire.Green, Ms3dFile.Materiaux(I).Speculaire.Blue

'Emetteur
Input #f, Ms3dFile.Materiaux(I).Emetteur.alpha, Ms3dFile.Materiaux(I).Emetteur.Red, Ms3dFile.Materiaux(I).Emetteur.Green, Ms3dFile.Materiaux(I).Emetteur.Blue

'Brillance
Input #f, Ms3dFile.Materiaux(I).Brillant

'Transparence
Input #f, Ms3dFile.Materiaux(I).Transparence

'Texture Diffuse
Input #f, Ms3dFile.Materiaux(I).DiffuseTexture

'Texture Alpha
Input #f, Ms3dFile.Materiaux(I).AlphaTexture

Next I
End If

Input #f, TempString 'ligne vide
Input #f, TempString ' "Bones : xx

If Ms3dFile.NbrStructure > 0 Then
ReDim Ms3dFile.Structure(Ms3dFile.NbrStructure - 1)

For I = 0 To Ms3dFile.NbrStructure - 1

'Nom
Input #f, Ms3dFile.Structure(I).Nom

'Nom de la structure mère
Input #f, Ms3dFile.Structure(I).NomParent

'time zero, Position, Rotation
Input #f, Ms3dFile.Structure(I).Flag, Ms3dFile.Structure(I).Position.x, Ms3dFile.Structure(I).Position.y, Ms3dFile.Structure(I).Position.z, Ms3dFile.Structure(I).Rotation.x, Ms3dFile.Structure(I).Rotation.y, Ms3dFile.Structure(I).Rotation.z

'Nbr de cle de position (=nombre de frames - time zero)
Input #f, Ms3dFile.Structure(I).NbrFrameCléPosition

If Ms3dFile.Structure(I).NbrFrameCléPosition >= 1 Then
ReDim Ms3dFile.Structure(I).FrameClePosition(Ms3dFile.Structure(I).NbrFrameCléPosition - 1)

'cle de position
For j = 0 To Ms3dFile.Structure(I).NbrFrameCléPosition - 1
Input #f, Ms3dFile.Structure(I).FrameClePosition(j).Durée, Ms3dFile.Structure(I).FrameClePosition(j).Position.x, Ms3dFile.Structure(I).FrameClePosition(j).Position.y, Ms3dFile.Structure(I).FrameClePosition(j).Position.z
Next j

End If

'Nbr de cle de rotation
Input #f, Ms3dFile.Structure(I).NbrFrameCléRotation

If Ms3dFile.Structure(I).NbrFrameCléRotation >= 1 Then
ReDim Ms3dFile.Structure(I).FrameCleRotation(Ms3dFile.Structure(I).NbrFrameCléRotation - 1)

' cle de rotation
For j = 0 To Ms3dFile.Structure(I).NbrFrameCléRotation - 1
Input #f, Ms3dFile.Structure(I).FrameCleRotation(j).Durée, Ms3dFile.Structure(I).FrameCleRotation(j).Rotation.x, Ms3dFile.Structure(I).FrameCleRotation(j).Rotation.y, Ms3dFile.Structure(I).FrameCleRotation(j).Rotation.z
Next j
End If
Next I

MakeParentDefBone
FindTotalFrame

End If
Frame = 0

Call SetupBones

fin:
Close #f

End Sub

Public Function MakeParentDefBone()
Dim I As Long, j As Long

For I = 0 To Ms3dFile.NbrStructure - 1
For j = 0 To Ms3dFile.NbrStructure - 1
If Ms3dFile.Structure(I).NomParent = Ms3dFile.Structure(j).Nom Then
Ms3dFile.Structure(I).ParentIndex = j
Exit For
Else
Ms3dFile.Structure(I).ParentIndex = -1
End If

Next j

Next I

End Function

Public Function FindTotalFrame()
Dim I As Long

For I = 0 To Ms3dFile.NbrStructure - 1
If NbrFrame < Ms3dFile.Structure(I).NbrFrameCléPosition - 1 Then
NbrFrame = Ms3dFile.Structure(I).NbrFrameCléPosition - 1
End If
If Ms3dFile.Structure(I).NbrFrameCléRotation - 1 > NbrFrame Then NbrFrame = Ms3dFile.Structure(I).NbrFrameCléRotation - 1
Next I

Form1.ProgressBar.Max = NbrFrame
End Function
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
26 avril 2007 à 19:17
hum j'ai recodé entierement la partie readms3d pour lire tout les ms3d mais apparament le probleme ne vient pas de la.

g testé avec mon modele jill animé mais elle est completement deformée comme si le modele etait inversé par rapport au squelette....

je me demande si il faut pas appliquer le squelette en position 0 a l'ensemble des points avant d'animer pour que ca marche avec les autres frames ?
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
25 avril 2007 à 20:21
Hum je vois a peu pres ce que tu veux dire je vais voir si j'ai le temps aussi ^^.
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
25 avril 2007 à 20:19
non non ca marche tres bien c'est juste ta partie lecture du fichier ascii qui bug (un bone du fichier diablo.txt est pris dans les vertex, donc tu as des points supplementaires et des faces supplementaires et des bones en moins d'ou une animation erronée..
c'est en partie du au fait que ton loader ne gere pas les models utilisant des groupes (abbey.txt est un seul groupe : monotexture) alors que diablo.txt est fragmenté en 14 groupes ayant chacun une texture (donc 14 textures)

voila ton "petit" bug fo juste implementer des structures group dans la partie load

voila bon courage... (je matterais si g le tps)
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
25 avril 2007 à 18:01
Je viens de mettre à jour.
Ps : CUQ, tu dis que certain note mal, mais tu enleves deux points pour deux type de rendu ^^.

En même temps je m'en fou des notes mettez 0 ou 10, cette source n'est pas la pour ca, seulement pour montrer à certain comment s'y prendre.
ciberrique Messages postés 589 Date d'inscription lundi 25 août 2003 Statut Membre Dernière intervention 18 juillet 2010 1
25 avril 2007 à 17:47
Bizarre le zip a était supprimer :s

Shadowmoy, merci pour ton aide, mais meme avec ta correction ca ne fonctionne pas pour tout les fichiers 3d, je vous en ajoute 2 dans le zip pour te montrer le bug.
cuq Messages postés 345 Date d'inscription mardi 3 juin 2003 Statut Membre Dernière intervention 21 mars 2008 2
25 avril 2007 à 17:18
Plutot Genial 8/10 -> les gens sont durs et dire que l'on a des 10 avec le calcul de l'intersection de deux droites en 2D ....

Bref : Plutot Genial 8/10, Genial 9/10 et donc Carrement GENIAL 10/10, ben je vai mettre Genial car les différents types de rendu marche pas chez moi ...
dthuler Messages postés 121 Date d'inscription dimanche 9 mars 2003 Statut Membre Dernière intervention 29 avril 2009
25 avril 2007 à 17:06
Zip? je le vois pas :´( ouin
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
25 avril 2007 à 15:55
bon :
Public Const Q_RAD = 57.2957795130824 '180 / Q_PI
ah oui et evite les integer pour tes def
ex:
Dim Indice As Integer, Vertex As Integer
tu fait comment si tu as plus de 32768 points dans ton model ? BOOM ca plante
utilise des longs plutot.

allé j'arrete la lol
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
25 avril 2007 à 15:48
pour booster un peu le framerate tu devrait essayer de pas recalculer les matrices a chaque frame comme le fait dx
en gros faire un type perso pour exporter les matrices precalculées de l'animation.
comme ca tu ne rebuild pas les matrices a chaque frame et ca speed un peut ton applis.

autre chose evite les : truc * 180 / QPI
defini une constante plutot ca evite de le recalculer 6 fois a chaque frames ...
voila bonne prog :p
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
25 avril 2007 à 15:39
voila :
dans ta fonction SetupBones il faut juste remplacer

D3DXMatrixRotationYawPitchRoll Ms3dFile.Structure(i).mRelative, vRot.y, vRot.x, vRot.z

par :
D3DXMatrixRotationX Ms3dFile.Structure(i).mRelative, vRot.x
D3DXMatrixRotationY Ms3dFile.Structure(i).mRelative, vRot.y
D3DXMatrixRotationZ Ms3dFile.Structure(i).mRelative, vRot.z
et la c ok :op

c'etait pas compliqué hein ?
sinon bonne conversion du code cpp dans l'ensemble mais fodrai optimiser
et virer surtout virer le timer
@++
ianis24 Messages postés 87 Date d'inscription dimanche 20 août 2006 Statut Membre Dernière intervention 13 janvier 2011
25 avril 2007 à 13:41
Plutot Genial 8/10
shadowmoy Messages postés 340 Date d'inscription jeudi 25 juillet 2002 Statut Membre Dernière intervention 25 août 2007
25 avril 2007 à 13:36
ah ben tu vois quand tu veux :op
je regarde pour le bug et je te dit quoi ..
Rejoignez-nous