
salut à tous,
j'ai fais une fonction pour dessiner des meshs genre : verre, bouteille (eh oui, fait chaud !), vase... , enfin tous ce qui présente une symétrie axial, et même plus
et j'ai pas été déçu par le résultat !
je vous mets cette démo pour illustrer mes fonctions:
- CreateAxialMeshCircular
- CreateAxialMeshCustom
(eh oui, j'ai même traduit in english!)
le principe est de définir un profil (et une section pour la fonction 'custom') decrivant le mesh
ces profils et sections sont définit par une série de point que j'interpole par une spline
une seule instruction permet de définir le mesh
vous verrez dans le code
ces fonctions sont assez abouties, j'espere que ça vous sera utile
en revanche pour les formes complexes, c’est un peu galère d'entrer les coordonnées des points de la spline
faudra que je fasse un petit éditeur..
(un petit defaut concernant l'ombrage au niveau de la jointure, j'ai pas trouvé la fonction qui va bien, j'espere que quelqu'un va corriger ça)
sinon j'ai remis mon petit mirroir qui bug sur les bord (à cause de Cameraprojection qui retourne -1 quand on sort de l'écran)
voilà
Code : Tout sélectionner
;Mesh Axial - Pf shadoko - 2015
EnableExplicit
Global.w ex,ey,dx,dx1,dy,dy1,nb
;###############################################################################
;###############################################################################
;###############################################################################
Structure coo2d
x.f
y.f
EndStructure
Procedure Bspline(Array pe.coo2d(1), Array PS.coo2d(1),nd.w)
Protected.f t,tt
Protected np,i,j,jj,k,c
Protected Dim m.w(4, 4)
Protected Dim ttt.f(4)
np = ArraySize(pe())
Protected Dim PS((np - 2) * nd)
m(0, 0) = -1: m(1, 0) = 3: m(2, 0) = -3: m(3, 0) = 1
m(0, 1) = 2: m(1, 1) = -5: m(2, 1) = 4: m(3, 1) = -1
m(0, 2) = -1: m(1, 2) = 0: m(2, 2) = 1: m(3, 2) = 0
m(0, 3) = 0: m(1, 3) = 2: m(2, 3) = 0: m(3, 3) = 0
If pe(np - 1)\X = pe(1)\X And pe(np - 1)\Y = pe(1)\Y
pe(0) = pe(np - 2): pe(np) = pe(2)
Else
pe(0) = pe(1):pe(np) = pe(np - 1)
EndIf
For jj = 0 To np - 3
For i = 0 To nd - 1
t = i / nd
For j = 0 To 3
ttt(j) = 0: tt = 1
For k = 3 To 0 Step -1: ttt(j) + tt * m(j, k) / 2: tt = tt * t: Next
PS(c)\X = PS(c)\X + ttt(j) * pe(j + jj)\X
PS(c)\Y = PS(c)\Y + ttt(j) * pe(j + jj)\Y
Next
c + 1
Next
Next
PS(c) = pe(np - 1)
EndProcedure
Procedure string2coo2d(Array s.coo2d(1),t.s) ;pas tres élégant !
Protected Dim a.f(0, 0)
Protected n
t="0,0/"+t+"/0,0"
ParseJSON(0, "[["+ReplaceString(t,"/","],[")+"]]")
ExtractJSONArray(JSONValue(0), a())
n=ArraySize(a())
Dim s.coo2d(n)
CopyMemory(@a(0,0),@s(0),4*2*(n+1))
EndProcedure
Procedure.f lg2D(x.f,y.f)
ProcedureReturn Sqr(x.f*x.f+y.f*y.f)
EndProcedure
Procedure CreateAxialMesh(mesh,Array profils.coo2d(1),Array section.coo2d(1))
Macro profilsJ()
ar=r
ah=h
r=profils(j)\x
h=profils(j)\y
v+lg2D(r-ar,h-ah)
EndMacro
Protected i,j,r.f,h.f,ar.f,ah.f,a.f,v.f,vv.f,n,n1,m
n=ArraySize(section()):n1=n+1
m=ArraySize(profils())
r=profils(0)\x:h=profils(0)\y:v=0
For j=0 To m:profilsJ():Next:vv=v
r=profils(0)\x:h=profils(0)\y:v=0
CreateMesh(mesh,#PB_Mesh_TriangleList,#PB_Mesh_Dynamic)
For j=0 To m
profilsJ()
For i=0 To n
MeshVertexPosition(section(i)\x* r,h,section(i)\y* r)
MeshVertexTextureCoordinate(i/n,v/vv)
MeshVertexNormal(0,0,0)
MeshVertexColor($ffffff)
Next
Next
For j=0 To m-1
For i=0 To n-1
MeshFace(i+j*n1,i+(j+1)*n1,(i%n1+1)+j*n1)
MeshFace((i%n1+1)+(j+1)*n1,(i%n1+1)+j*n1,i+(j+1)*n1)
Next
Next
FinishMesh(1)
NormalizeMesh(mesh)
;BuildMeshTangents(Mesh)
EndProcedure
Procedure CreateAxialMeshCustom(mesh,ProfilList.s,ProfilSubDiv,sectionList.s,SectionSubDiv)
Protected Dim profil.coo2d(0)
Protected Dim profils.coo2d(0)
string2coo2d(profil(),ProfilList)
Bspline(profil(),profils(),ProfilSubDiv)
Protected Dim section.coo2d(0)
Protected Dim sections.coo2d(0)
string2coo2d(section(),sectionList)
Bspline(section(),sections(),SectionSubDiv)
CreateAxialMesh(mesh,profils(),sections())
EndProcedure
Procedure CreateAxialMeshCircular(mesh,ProfilList.s,ProfilSubDiv=16 ,cercleSubDiv=16)
Protected i,a.f
Protected Dim profil.coo2d(0)
Protected Dim profils.coo2d(0)
string2coo2d(profil(),ProfilList)
Bspline(profil(),profils(),ProfilSubDiv)
Protected Dim section.coo2d(cercleSubDiv)
For i=0 To cercleSubDiv:a=Radian(360/cercleSubDiv)*i:section(i)\x=Cos(a):section(i)\y=Sin(a):Next
CreateAxialMesh(mesh,profils(),section())
EndProcedure
;###############################################################################
;###############################################################################
;###############################################################################
Procedure degrade(Array pal.l(1),l,c1.l,c2.l)
Dim pal(l-1)
CreateImage(0,l,1,32)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_Gradient)
GradientColor(0.0,c1)
GradientColor(1.0,c2)
LinearGradient(0,0,l-1,0)
Box(0,0,l,1)
CopyMemory(DrawingBuffer(),@pal(0),l*4)
StopDrawing()
FreeImage(0)
EndProcedure
Procedure generematiere(num,dx,dy,c1,c2,type)
Protected i,j,y
Protected Dim pal.l(0):degrade(pal(),256,c1,c2)
CreateTexture(num,dx,dy)
StartDrawing(TextureOutput(num))
Select type
Case 1; point (assiette /pomme / coupe)
For j=0 To dy-1:For i=0 To dx-1:Plot(i,j,pal(Random(255))):Next:Next
Case 2; tissu (boite)
For i=0 To 2000:Line(Random(dx),0,1,dy,pal(Random(127)+128)):Line(0,Random(dy),dx,1,pal(Random(127))):Next
Case 3; brasselet
For i=-dx To dx:LineXY(i,0,i+dx,dy,pal(Bool(i & 30)*255)):Next
Case 4; vase
For j=0 To dy-1:For i=0 To dx-1:y=((Cos(i*4*#PI/dx)*255)): Plot(i ,j,pal((j*5+y) & 255)):Next:Next
Case 5; verre
Box(0,0,dx,dy,$ffffff):For j=0 To dy Step 32:Box (0,j,dx,4,$8800):Box (j,0,4,dy,$88):Next
EndSelect
StopDrawing()
CreateMaterial(num, TextureID(num))
EndProcedure
Procedure scene()
Protected i,j,k,c,x,y,dx=8,dy=8
;######################################## cameras
;principale
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0, 1000, 500, 0, #PB_Absolute):CameraLookAt(0, 0, 100, 0):CameraBackColor(0, $333333)
;miroir
CreateCamera(1, 0, 0,50,50):CameraBackColor(1, $333333)
CreateLight(0,$ffffff, 10000, 10000, 5000)
AmbientColor($222222)
;WorldShadows(#PB_Shadow_Additive,-1,$aaaaaa)
;######################################## textures / material
CreateRenderTexture(0,CameraID(1),ex,ey)
CreateMaterial(0, TextureID(0))
SetMaterialColor(0,#PB_Material_DiffuseColor,$777777):MaterialBlendingMode(0,#PB_Material_Add)
generematiere(1,256,256,$ff0000,$ffff00,2) :ScaleMaterial(1,0.25,0.25)
generematiere(2,256,256,$ffcc88,$ccaa66,1)
generematiere(3,128,256,$443300,$222200,1)
generematiere(4,64,64,$aaaaff,$ffffaa,1)
generematiere(5,256,256,$0000ff,$ffcc22,3)
generematiere(6,256,256,$ffffff,$cc9999,4) :ScaleMaterial(6,0.25,0.25)
generematiere(7,256,256,$ffffff,$ffcc00,5)
generematiere(8,8,8,$999900,$cc0000,1)
generematiere(9,256,256,$ff8800,$88ff88,2) :ScaleMaterial(9,0.25,0.25)
;######################################## mesh/entity
;CreateSphere (2,100):CreateEntity(2, MeshID(2), MaterialID(1),0,100,0)
;table+vitre
CreateAxialMeshCircular(1,"500,0/0,0",8,32)
CreateEntity(1, MeshID(1), MaterialID(0))
CreateAxialMeshCircular(2,"500,0/0,0",1,32)
CreateEntity(2, MeshID(2), MaterialID(3),0,-1,0)
;coupes
CreateAxialMeshCircular(10,"0,0/50,1/10,20/10,100/55,200/50,200/0,100",4,32)
CreateEntity(10, MeshID(10), MaterialID(4),0,0,-300)
CreateEntity(11, MeshID(10), MaterialID(4),200,0,-320)
;assiette
CreateAxialMeshCircular(12,"0,0/100,1/160,47/157,50/75,10/0,10",1,8)
CreateEntity(12, MeshID(12), MaterialID(2),250,0,250)
;vases
CreateAxialMeshCircular(13,"0,0/80,1/120,150/80,250/110,300/100,300/75,250/75,20/0,20",8,32)
CreateEntity(13, MeshID(13), MaterialID(6),-0,0,0)
;boite
CreateAxialMeshCircular(14,"0,0/80,1/110,70/85,140/90,140/90,150/10,160/20,190/0,200",4,4)
CreateEntity(14, MeshID(14), MaterialID(1),-200,0,-200)
;brasselet !!!! pour faire un tore, le premier point doit etre similaire au premier !!!!
CreateAxialMeshCircular(15,"45,15/45,0/55,15/45,30/45,15",4,32)
CreateEntity(15, MeshID(15), MaterialID(5),400,0,100)
;verre
CreateAxialMeshCircular(16,"0,0/50,1/60,150/55,150/45,10/0,10",1,32)
CreateEntity(16, MeshID(16), MaterialID(7),0,0,200)
;pommes
CreateAxialMeshCircular(17,"0,10/20,0/45,30/50,80/20,100/2,90/1,100/0,105",4,32)
CreateEntity(17, MeshID(17), MaterialID(8),230,10+10,300)
CreateEntity(18, MeshID(17), MaterialID(8),320,10+10,250)
CreateEntity(19, MeshID(17), MaterialID(8),260,10+10,170)
;truc (custom (ici on definit la section))
CreateAxialMeshCustom(20,"0,0/56,1/62,34/64,40/61,43/58,40/60,34/52,6/0,4",4,"-0.8,0/-1,-1/1,-1/0.8,0/1,1/-1,1/-0.8,0",8)
CreateEntity(20, MeshID(20), MaterialID(9),300,0,-100)
EndProcedure
Procedure rendermirror2(mesh,camP,camM)
Protected c,n,mx,my
Protected.f xp,yp,zp,xd,yd,zd
Protected Dim T.PB_MeshVertex(0)
xp=CameraX(camP):xd=CameraDirectionX(camP)
yp=CameraY(camP):yd=CameraDirectionY(camP)
zp=CameraZ(camP):zd=CameraDirectionZ(camP)
CameraDirection(camM,xd,-yd,zd)
MoveCamera(camM,xp,-yp,zp,#PB_Absolute)
mx=ex ;CameraViewWidth (camM) ;marche pas,
my=ey ;CameraViewHeight(camM) ;pas compris !
n=MeshVertexCount(mesh)-1
GetMeshData(mesh,0,t(),#PB_Mesh_Vertex|#PB_Mesh_UVCoordinate ,0,n)
For c=0 To n
With t(c)
\u= CameraProjectionX(1,\x, 0,\z)/mx
\v= CameraProjectionY(1,\x, 0,\z)/my
EndWith
Next
SetMeshData(mesh,0,t(),#PB_Mesh_Vertex|#PB_Mesh_UVCoordinate,0,MeshVertexCount(mesh)-1)
EndProcedure
Define.f KeyX, KeyY,keyz, MouseX, MouseY,time,v,a,x,y,z,r.l
Define i,j,c,px,py,p,shadingmode
InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()
OpenWindow(0, 0, 0, 0,0, " Mesh Axial",#PB_Window_Maximize)
ex=WindowWidth (0,#PB_Window_InnerCoordinate)
ey=WindowHeight(0,#PB_Window_InnerCoordinate)
OpenWindowedScreen(WindowID(0), 0, 0, ex, ey, 0, 0, 0)
Macro DT(t1,t2)
DrawText(4,p,t1)
DrawText(40,p,t2)
p+16
EndMacro
CreateSprite(0,120,170,#PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(0))
DrawingMode(#PB_2DDrawing_AlphaClip|#PB_2DDrawing_Outlined )
Box(0,0,120,170)
BackColor($0000ff)
dt("Déplacements:","")
dt("[Left]","")
dt("[Right]","")
dt("[Up]","")
dt("[Down]","")
dt("Mouse+wheel","")
dt("","")
dt("Commandes:","")
dt("[F1]","fil de fer")
dt("[Esc]","Quitter")
StopDrawing()
scene()
Repeat
WindowEvent()
ExamineMouse()
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
ExamineKeyboard()
keyx=(-Bool(KeyboardPushed(#PB_Key_Left)<>0)+Bool(KeyboardPushed(#PB_Key_Right)<>0))*4
keyz=(-Bool(KeyboardPushed(#PB_Key_Down)<>0)+Bool(KeyboardPushed(#PB_Key_Up )<>0))*4+MouseWheel()*50
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):MoveCamera (0, KeyX, keyy, -keyz)
If KeyboardReleased(#PB_Key_F1)
If shadingmode=#PB_Material_Wireframe:shadingmode=#PB_Material_Solid:Else:shadingmode=#PB_Material_Wireframe:EndIf
For i=0 To 9:MaterialShadingMode(i, shadingmode):Next
EndIf
rendermirror2(1,0,1)
time+RenderWorld()/200
DisplayTransparentSprite(0, 8,8,128)
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
End