PB 6 integre toutes les fonctions pour la création de squelette et la création d' animation
Code : Tout sélectionner
Procedure GetSafeFunction(Library, FunctionName$)
*Function = GetFunction(0, FunctionName$)
If *Function = 0:MessageRequester("Error", "Function "+FunctionName$+"() not found in Engine3D.dll"):End:EndIf
ProcedureReturn *Function
EndProcedure
OpenLibrary(0, #PB_Compiler_Home+"Compilers\engine3d.dll")
;#################################################################################################################
Prototype PBO_CreateSkeleton(meshid): Global PBO_CreateSkeleton.PBO_CreateSkeleton = GetSafeFunction(0, "PBO_CreateSkeleton")
Prototype PBO_CreateBone(meshid, joint.s, parentjoint.s, px.f, py.f, pz.f, ox.f, oy.f, oz.f, ow.f,omode): Global PBO_CreateBone.PBO_CreateBone = GetSafeFunction(0, "PBO_CreateBone")
;Prototype PBO_setBoneInitialState(meshid, joint.s, px.f, py.f, pz.f, ox.f, oy.f, oz.f, ow.f,omode): Global PBO_setBoneInitialState.PBO_setBoneInitialState = GetSafeFunction(0, "PBO_setBoneInitialState")
Prototype PBO_VertexBoneAssignment(meshid, submesh, vertexindex, boneindex, weight.f): Global PBO_VertexBoneAssignment.PBO_VertexBoneAssignment = GetSafeFunction(0, "PBO_VertexBoneAssignment")
Prototype PBO_FinishBoneAssignment(meshid, submesh): Global PBO_FinishBoneAssignment.PBO_FinishBoneAssignment = GetSafeFunction(0, "PBO_FinishBoneAssignment")
Prototype PBO_CreateSkeletonAnimation(meshID, animname.s,length.f): Global PBO_CreateSkeletonAnimation.PBO_CreateSkeletonAnimation = GetSafeFunction(0, "PBO_CreateSkeletonAnimation")
Prototype PBO_AddSkeletonAnimationKeyFrame (meshID, animname.s, bonename.s,time.f, ox.f,oy.f,oz.f,ow.f,omode): Global PBO_AddSkeletonAnimationKeyFrame.PBO_AddSkeletonAnimationKeyFrame = GetSafeFunction(0, "PBO_AddSkeletonAnimationKeyFrame")
Prototype PBO_AddSkeletonAnimationKeyFrame2(meshID, animname.s, bonename.s,time.f, ox.f,oy.f,oz.f,ow.f,omode,tx.f,ty.f,tz.f): Global PBO_AddSkeletonAnimationKeyFrame2.PBO_AddSkeletonAnimationKeyFrame2 = GetSafeFunction(0, "PBO_AddSkeletonAnimationKeyFrame2")
Prototype PBO_AddSkeletonAnimationKeyFrame3(meshID, animname.s, bonename.s,time.f, ox.f,oy.f,oz.f,ow.f,omode,tx.f,ty.f,tz.f,sx.f,sy.f,sz.f): Global PBO_AddSkeletonAnimationKeyFrame3.PBO_AddSkeletonAnimationKeyFrame3 = GetSafeFunction(0, "PBO_AddSkeletonAnimationKeyFrame3")
Prototype PBO_ScaleEntityBone(entityid, joint.s, sx.f, sy.f, sz.f,options): Global PBO_ScaleEntityBone.PBO_ScaleEntityBone = GetSafeFunction(0, "PBO_ScaleEntityBone")
Enumeration orientation
; #PB_Orientation_Absolute= 0
; #PB_Orientation_Relative= (1 << 0)
; #PB_Orientation_Local= (1 << 1)
; #PB_Orientation_Parent= (1 << 2)
; #PB_Orientation_World= (1 << 3)
#PB_Orientation_PitchYawRoll= (1 << 7)
#PB_Orientation_Quaternion= (1 << 8)
#PB_Orientation_AngleAxis= (1 << 9)
#PB_Orientation_DirectionLDVX= (1 << 10)
#PB_Orientation_DirectionLDVY= (1 << 11)
#PB_Orientation_DirectionLDVZ= (1 << 12)
#PB_Orientation_DirectionLDVXN= (1 << 13)
#PB_Orientation_DirectionLDVYN= (1 << 14)
#PB_Orientation_DirectionLDVZN= (1 << 15)
;#PB_Orientation_Direction= #PB_Orientation_DirectionLDVZN=(1 << 15) ; Alias
EndEnumeration
;#################################################################################################################
Macro f3:vector3:EndMacro
Macro f4:vector4:EndMacro
;{ ============================= biblio
Structure MeshVertexV
p.f3
n.f3
t.f3
u.f
v.f
color.l
EndStructure
Procedure f3(*v.f3,vx.f,vy.f,vz.f)
*v\x=vx
*v\y=vy
*v\z=vz
EndProcedure
Procedure f4(*v.f4,vx.f,vy.f,vz.f,vw.f)
*v\x=vx
*v\y=vy
*v\z=vz
*v\w=vw
EndProcedure
Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
*p\x=*p1\x-*p2\x
*p\y=*p1\y-*p2\y
*p\z=*p1\z-*p2\z
EndProcedure
Procedure add3d(*p.f3,*p1.f3,*p2.f3)
*p\x=*p1\x+*p2\x
*p\y=*p1\y+*p2\y
*p\z=*p1\z+*p2\z
EndProcedure
Procedure mul3d(*p1.f3,v.f)
*p1\x*v
*p1\y*v
*p1\z*v
EndProcedure
Procedure Mix3D(*R.f3, *V1.f3, *V2.f3, r.f)
*R\x = *V1\x + r * (*V2\x - *V1\x)
*R\y = *V1\y + r * (*V2\y - *V1\y)
*R\z = *V1\z + r * (*V2\z - *V1\z)
EndProcedure
Procedure.f lng3D(*v.f3)
ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
EndProcedure
Procedure.f dist3D(*p1.f3,*p2.f3)
Protected v.f3
sub3d(v,*p2,*p1)
ProcedureReturn Sqr(V\x * V\x + V\y * V\y + V\z * V\z)
EndProcedure
Procedure Norme3D(*V.f3,l.f=1)
Protected.f lm
lm = l / lng3d(*v)
*V\x * lm
*V\y * lm
*V\z * lm
EndProcedure
Procedure cross3d(*r.f3,*p.f3,*q.f3)
*r\x=*p\y * *q\z - *p\z * *q\y
*r\y=*p\z * *q\x - *p\x * *q\z
*r\z=*p\x * *q\y - *p\y * *q\x
EndProcedure
Procedure.f dot3d(*p.f3,*q.f3)
ProcedureReturn *p\x * *q\x + *p\y * *q\y + *p\z * *q\z
EndProcedure
Procedure.f Max(v1.f,v2.f)
If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
EndProcedure
Procedure.f Min(v1.f,v2.f)
If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
EndProcedure
Procedure.f clamp(V.f, i.f, s.f)
If V < i :v=i:EndIf
If V > s :v=s:EndIf
ProcedureReturn V
EndProcedure
;}
Procedure.f pproche(*i.f3,*p.f3,*p1.f3,*p2.f3)
Protected k.f,v.f3,p.f3
sub3d(v,*p2,*p1)
sub3d(p,*p,*p1)
k= (v\x * p\x + v\y * p\y + v\z * p\z )/( v\x * v\x + v\y * v\y + v\z * v\z)
k=clamp(k,0,1)
f3(*i,k* v\x, k* v\y, k* v\z):add3d(*i,*i,*p1)
ProcedureReturn k
EndProcedure
Procedure line3dex(n,*p1.f3,c1.l,*p2.f3,c2.l,relatif)
If relatif
CreateLine3D(n,*p1\x,*p1\y,*p1\z,c1 ,*p1\x+*p2\x,*p1\y+*p2\y,*p1\z+*p2\z,c2)
Else
CreateLine3D(n,*p1\x,*p1\y,*p1\z,c1 ,*p2\x,*p2\y,*p2\z,c2)
EndIf
EndProcedure
Structure sjoint
id.l
idp.l
ids.l
p.f3
EndStructure
Global Dim joint.sjoint(100)
Procedure meshboneassignement(mesh)
Protected i,j,nv1,nf1,color
Protected.f l,d,h, lmin, dmin,w
Protected.f3 p,px,pxmin,v
Protected.sjoint j1,j0,j1min,j0min
nv1=MeshVertexCount(mesh)-1
Dim lp.MeshVertexV(0)
GetMeshData(mesh,0,lp(),#PB_Mesh_Vertex,0,nv1)
For i=0 To nv1
lmin=10000
For j=1 To ArraySize(joint())
j1=joint(j)
j0=joint(j1\idp)
d=pproche(px,lp(i),j1\p,j0\p)
l=dist3d(lp(i),px):If l<lmin:lmin=l:j1min=j1:j0min=j0:pxmin=px:dmin=d:EndIf
Next
; d=dist3D(joint(joint(jmin)\idp),pxmin)
; h=dist3D(lp(i),pxmin)
; If h>0:dmin=clamp(d/h,0,1):Else:dmin=1:EndIf
If dmin<0.5
b1=j1min\id:b0=j1min\idp:w=dmin+0.5
Else
b1=j0min\id:b0=j0min\idp:w=dmin-0.5
EndIf
PBO_VertexBoneAssignment(mesh,0,i,b1,1-w)
PBO_VertexBoneAssignment(mesh,0,i,b0,w)
Next
PBO_FinishBoneAssignment(0,0)
EndProcedure
InitEngine3D():InitSprite():InitKeyboard():InitMouse()
OpenWindow(0, 0,0, 1280,720, "Animation 3d - [F12] Wireframe - [Esc] quit",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0), 0, 0, 0)
Add3DArchive(GetCurrentDirectory(), #PB_3DArchive_FileSystem)
Parse3DScripts()
CreateCamera(0, 0, 0, 100, 100):MoveCamera(0,-2,2,2):CameraLookAt(0,0,1,0):CameraRange(0,0,1000)
CreateLight(0,$ffffff, -1000, 1000, 0)
AmbientColor($444444)
CameraBackColor(0,$8888aa)
CreateSphere(100,0.01)
CreateMaterial(100,0,$ffffff)
Define pjoint.s,joint.s,nbjoint=3,n=16*(nbjoint+1),w.f,l.f
;CreateShaderMaterial(0,#PB_Material_ColorShader):SetMaterialColor(0,3,$88ff):MaterialShininess(0,64,$ffffff)
CreateMaterial(0,0,$88ff):MaterialShininess(0,64,$ffffff)
LoadMesh(0,"man.mesh")
;{ ======================================== skeleton
Procedure defjoint(num,nums,parent,px.f,py.f,pz.f,ox.f=1,oy.f=0,oz.f=0,ow.f=0,omode=#PB_Orientation_AngleAxis)
Protected.s pjoint
f3(joint(num)\p,px,py,pz)
joint(num)\id =num
joint(num)\ids=nums
joint(num)\idp=max(parent,0)
If parent>=0:pjoint="joint"+parent:EndIf
PBO_createBone(0,"joint"+num,pjoint,px,py,pz,ox,oy,oz,ow,omode)
If nums
If joint(parent)\ids:parent=joint(parent)\ids:EndIf
pjoint="joint"+parent
PBO_createBone(0,"joint"+nums,pjoint,-px,py,pz,ox,oy,oz,ow,omode)
f3(joint(nums)\p,-px,py,pz)
joint(nums)\id =nums
joint(nums)\idp =parent
EndIf
EndProcedure
PBO_CreateSkeleton(0)
defjoint(0,0,-1 ,0, 1.0,0)
defjoint(1,2,0 ,-0.12, 0.9,0.05)
defjoint(3,4,1 ,-0.2, 0.5,0)
defjoint(5,6,3 ,-0.3, 0,-0.05)
defjoint(7,8,5 ,-0.3, 0,0.1)
defjoint(9,0,0 ,0, 1.3,0)
defjoint(10,0,9 ,0,1.6,0)
defjoint(11,12,9, 0.22, 1.5,0.02)
defjoint(13,14,11,0.35, 1.25,0)
defjoint(15,16,13,0.58, 0.96,0.1)
defjoint(17,18,15,0.65, 0.90,0.1)
defjoint(19,0,10 ,0,1.8,0)
ReDim joint(19)
;}
For i=0 To 19:CreateEntity(100+i,MeshID(100),MaterialID(100)):Next
meshboneassignement(0)
;{ ======================================== animation
Global kfomode=#PB_Orientation_DirectionLDVY,animname.s="walk",kflength.f=1
Procedure kfadd(bone,time.f,ox.f,oy.f,oz.f,ow.f, tx.f=0,ty.f=0,tz.f=0)
Macro addkf(bone,time,sens=1):PBO_AddSkeletonAnimationKeyFrame2(0,animname,"joint"+bone,time,ox*sens,oy,oz,ow*sens,kfomode,tx,ty,tz):EndMacro
time/100*kflength
addkf(bone,time):If time=0:addkf(bone,kflength):EndIf
bones= joint(bone)\ids
If bones
time=Mod(time+kflength/2,kflength)
addkf(bones,time,-1):If time=0:addkf(bones,kflength,-1):EndIf
EndIf
EndProcedure
PBO_CreateSkeletonAnimation(0,animname, kflength)
kfadd(0,0, 0,5,0,20, 0,0.1)
kfadd(0,25, 0,5,0,0, 0,0)
kfadd(0,50, 0,5,0,-20, 0,0.1)
kfadd(0,75, 0,5,0,0, 0,0)
kfadd(1,0,0,6,-8,-10)
kfadd(1,50,-2,8,4,10)
kfadd(3,0,0,4,1,0)
kfadd(3,25,0,4,1,0)
kfadd(3,50,0,-1,4,0)
kfadd(3,75,0,-1,4,0)
kfadd(9,0,0,5,0,-30)
kfadd(9,50,0,5,0,30)
kfadd(11,0,1,2,-6,0)
kfadd(11,50,1,1,4,0)
kfadd(13,0,5,5,-2,-30)
kfadd(13,50,0,-1,-5,-30)
;}
CreateEntity(0,MeshID(0),MaterialID(0))
Procedure affbones()
Protected i,joint.s
For i=0 To ArraySize(joint())
joint="joint"+i
MoveEntity(100+i,EntityBoneX(0,joint),EntityBoneY(0,joint),EntityBoneZ(0,joint),#PB_Absolute)
Next
EndProcedure
Define.f MouseX,Mousey,depx,depz,dist,rotx,fdf.l,jn.l=11
StartEntityAnimation(0,"walk")
Repeat
While WindowEvent():Wend
ExamineKeyboard()
ExamineMouse()
depx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.05
depz=(-Bool(KeyboardPushed(#PB_Key_Down))+Bool(KeyboardPushed(#PB_Key_Up )))*0.05+MouseWheel()*1
If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:EndIf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf
MouseX = -MouseDeltaX() * 0.05
MouseY = -MouseDeltaY() * 0.05
RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
dist+(depz-dist)*0.05:MoveCamera (0, depX, 0, -dist)
affbones()
RenderWorld()
FlipBuffers()
Until KeyboardReleased(#PB_Key_Escape) Or MouseButton(3)