I haven't done much work with the latest version of PB. So, I figured maybe someone could give me a heads up on this.
I know that you can now update your vertex position, but can it compete with giving your entity a skeleton?
I've seen the newest demos, like the flag one, and they look pretty fast, but how well would this work on a more complicated mesh?
I asking because I'm starting a little project and I would like to manipulate my meshes just using PB commands, but I'm just not sure how well
it can handle it. My meshes won't be to big. Most will just have a 100 or 200 points, but some may get near a 1000.
I can give more info if needed. Thanks!
Question on MeshVertexPosition()'s speed.
Re: Question on MeshVertexPosition()'s speed.
Hi Samuel
about the skeleton i have'nt studied the subject yet, but about changing and updating the vertex position i have some ideas i get by stripping down the official example MeshManualParametrics.pb until i leave no math.
i have asked myself how to change MeshVertexPosition(x,y,z) if it adds index internaly ie there is no MeshVertexPosition(index,x,y,z) so to manipulate the position dynamically after mesh creation it is only available for MeshFace and MeshIndex functions and not for MeshVertexPosition. but there is UpdateMesh() to put the internal index again at the beginning to recalculate the positions again.
you said what about complex mesh ?? the good news is that we don't need to contineously calculating the positions inside main loop repeat ... untill exit
since the graphics are persistent and the mesh are there exit and alive in memory. so only we calculate the positions on demand. but of course i wish like you a MeshVertexPosition(index,x,y,z) version. the MeshIndex works like MeshFace but on arbitrary vertices it can weave connections between more than 3 vertices unlike meshface() as demonstrated in example MeshManual2.pb
the following example demonstrate how to update a vertice position continuously by pressing keys and without inserting the update process inside the main loop and this relieves the cpu from the continuous heavy tasks.
press the arrow keys to move one vertex ,press f3 for solid, f2 for wire.
i am still researching the subject.
about the skeleton i have'nt studied the subject yet, but about changing and updating the vertex position i have some ideas i get by stripping down the official example MeshManualParametrics.pb until i leave no math.
i have asked myself how to change MeshVertexPosition(x,y,z) if it adds index internaly ie there is no MeshVertexPosition(index,x,y,z) so to manipulate the position dynamically after mesh creation it is only available for MeshFace and MeshIndex functions and not for MeshVertexPosition. but there is UpdateMesh() to put the internal index again at the beginning to recalculate the positions again.
you said what about complex mesh ?? the good news is that we don't need to contineously calculating the positions inside main loop repeat ... untill exit
since the graphics are persistent and the mesh are there exit and alive in memory. so only we calculate the positions on demand. but of course i wish like you a MeshVertexPosition(index,x,y,z) version. the MeshIndex works like MeshFace but on arbitrary vertices it can weave connections between more than 3 vertices unlike meshface() as demonstrated in example MeshManual2.pb
the following example demonstrate how to update a vertice position continuously by pressing keys and without inserting the update process inside the main loop and this relieves the cpu from the continuous heavy tasks.
press the arrow keys to move one vertex ,press f3 for solid, f2 for wire.
i am still researching the subject.
Code: Select all
Global Epsilon2.f = 5
Global Epsilon1.f = 1
#Scale = 0.4
IncludeFile "Screen3DRequester.pb"
Define.f KeyX, KeyY
Declare CreatePoly()
Declare UpdatePoly()
Declare Poly()
Declare Poly3()
If InitEngine3D()
Add3DArchive("/", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/Sources\Data", #PB_3DArchive_FileSystem)
InitSprite()
InitKeyboard()
If Screen3DRequester()
CreatePoly()
CreateMaterial(0, LoadTexture(0, "White.jpg"))
DisableMaterialLighting(0, #True)
MaterialShadingMode(0, #PB_Material_Wireframe )
MaterialCullingMode(0, #PB_Material_NoCulling)
SetMeshMaterial(0, MaterialID(0))
node = CreateNode(#PB_Any)
AttachNodeObject(node, MeshID(0))
ScaleNode(node, #scale, #scale, #scale)
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 50, #PB_Absolute)
CameraFOV(0, 40)
CameraBackColor(0, $330000)
CameraLookAt(0,0,0,0)
CreateLight(0, RGB(255,255,255), 10, 60, -10)
AmbientColor(RGB(90, 90, 90))
Repeat
Screen3DEvents()
If ExamineKeyboard()
If KeyboardReleased(#PB_Key_F2)
MaterialShadingMode(0, #PB_Material_Wireframe)
ElseIf KeyboardReleased(#PB_Key_F3)
MaterialShadingMode(0, #PB_Material_Solid)
EndIf
If KeyboardPushed(#PB_Key_Right)
Epsilon2 + 0.4 :Poly3()
ElseIf KeyboardPushed(#PB_Key_Left)
Epsilon2 - 0.4 :Poly3()
EndIf
If KeyboardPushed(#PB_Key_Up)
Epsilon1 + 0.4:Poly3()
ElseIf KeyboardPushed(#PB_Key_Down)
Epsilon1 - 0.4 :Poly3()
EndIf
EndIf
rot.f+0.6
;UpdatePoly() ; no need here
;RotateNode(node,0,rot,0)
RenderWorld()
;Screen3DStats()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
End
Procedure CreatePoly()
CreateMesh(0, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
Poly()
FinishMesh(#False)
EndProcedure
Procedure UpdatePoly()
UpdateMesh(0, 0)
Poly()
FinishMesh(#False)
EndProcedure
Procedure Poly()
MeshVertexPosition(-Epsilon2, Epsilon1, -20)
MeshVertexColor(RGB(255, 255, 0))
MeshVertexPosition(30, 30, -30)
MeshVertexColor(RGB(255, 255, 0))
MeshVertexPosition(15, -55, -15)
MeshVertexColor(RGB(255, 255, 0))
MeshVertexPosition(2, 1,0)
MeshFace(0, 1, 2)
MeshFace(1, 2, 3)
EndProcedure
Procedure Poly3()
UpdateMesh(0, 0)
;MeshIndex(2)
MeshVertexPosition(-Epsilon2, Epsilon1, -20)
MeshVertexColor(RGB(255, 0, 0))
MeshVertexPosition(30, 30, -30)
MeshVertexColor(RGB(255, 255, 0))
MeshVertexPosition(15, -55, -15)
MeshVertexColor(RGB(0, 255, 0))
MeshVertexPosition(2, 1,0)
MeshVertexColor(RGB(0, 255, 250))
MeshFace(0, 1, 2)
MeshFace(1, 2, 3)
FinishMesh(#False)
EndProcedure
-
DarkDragon
- Addict

- Posts: 2348
- Joined: Mon Jun 02, 2003 9:16 am
- Location: Germany
- Contact:
Re: Question on MeshVertexPosition()'s speed.
Skeletons can be hardware accelerated through vertex shaders. You'll loose this advantage through manual vertex animation.
bye,
Daniel
Daniel
Re: Question on MeshVertexPosition()'s speed.
another experiment, i will use a sphere made from circles which are made from points like this:
and then attach triangles between the points on every circle and the points on the next circle then make texturing, i have copied the procedure from my previous klein and mobius examples, so the texturing are not correct and flicker , but the purpose is to show that morphing speed are good even on the huge number of vertices (here it is 1500 ) and that depends on the heavy usage of sin,cos,tan etc functions. you can try other morphing equations.
the morphing are inside morph() procedure ,press W to toggle wire/solid
Code: Select all
Enumeration
#MESH
#LIGHT
#CAMERA_ONE
#BUTTON
#mainwin
EndEnumeration
Quit.b = #False
rot.l=1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0
ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), " sphere from circles ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
InitKeyboard()
SetFrameRate(60)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(#CAMERA_ONE, 0, 0, 400, 400)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)
RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf
;SkyDome("clouds.jpg", 100) ;for blue color background
;- Mesh
CreateTexture(0,32,32)
StartDrawing(TextureOutput(0))
Box(0,0,32,32,RGB(255,255,255))
StopDrawing()
CreateMaterial(0,TextureID(0))
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static)
DisableMaterialLighting(0, #True)
SetMeshMaterial(1, MaterialID(0))
x.f: y.f :z.f : u.f: v.f: r.f
majorOrbit.l = 100 : minorOrbit.l = 100
majorStep.f = 2 * #PI / majorOrbit
minorStep.f = 2 * #PI / minorOrbit
i.l: j.l
For i = 0 To 100
u = i * majorStep
For j = 0 To minorOrbit
v = j * minorStep
r = 4 * (1 - (Cos(u)/2))
x = Cos(u) * Cos(v)
y = Sin(u) * Cos(v)
z.f = Sin(v)
MeshVertexPosition(x, y, z);
MeshVertexColor(RGB(0,255,0))
Next
Next
NormalizeMesh(1)
FinishMesh(#True)
CreateEntity(1, MeshID(1), MaterialID(0))
ScaleEntity(1,3, 3, 3)
;Main loop
MoveEntity(1,0,up,depth,#PB_Absolute)
x = 180: y=0: z=0 : h.f
Repeat
Event = WindowEvent()
x + rotx
y + roty
z + rotz
RotateEntity(1, x, y, z)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
the morphing are inside morph() procedure ,press W to toggle wire/solid
Code: Select all
Enumeration
#MESH
#LIGHT
#CAMERA_ONE
#BUTTON
#mainwin
EndEnumeration
Declare morph()
Global Epsilon2.f = 5
Global Epsilon1.f = 1
Global amplitude.f = 5
Global freq.f = 1.0
Quit.b = #False : wireFrame.b = 1
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0
ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate, QA far/near, key_pad R/L/U/D", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop")
;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
;WorldShadows(#PB_Shadow_Additive)
InitKeyboard()
SetFrameRate(60)
Add3DArchive("/", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "Examples/Sources\Data", #PB_3DArchive_FileSystem)
CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))
CreateCamera(#CAMERA_ONE, 0, 0, 400, 400)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)
RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf
SetActiveGadget(#BUTTON)
;SkyDome("clouds.jpg", 100) ;for blue color background
;- Mesh
CreateMaterial(0, LoadTexture(0, "terrain_texture.jpg"))
MaterialShadingMode(0, #PB_Material_Wireframe)
MaterialCullingMode(0, #PB_Material_NoCulling)
CreateMesh(1, #PB_Mesh_TriangleList, #PB_Mesh_Static)
DisableMaterialLighting(0, #True)
SetMeshMaterial(1, MaterialID(0))
node = CreateNode(#PB_Any)
AttachNodeObject(node, MeshID(1))
ScaleNode(node, 1, 1, 1)
x.f: y.f :z.f : u.f: v.f: r.f
majorOrbit.l = 50 : minorOrbit.l = 30
majorStep.f = 2 * #PI / majorOrbit
minorStep.f = 2 * #PI / minorOrbit
i.l: j.l :txu.f : txv.f
For i = 0 To majorOrbit
v = i * majorStep
For j = 0 To minorOrbit
u = j * minorStep
r = 4 * (1 - (Cos(u)/2))
x = Cos(u) * Cos(v)
y = Sin(u) * Cos(v)
z.f = Sin(v)
MeshVertexPosition(x, y, z);
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
;texture the whole sphere with one picture stretched
txv = txv + 1/minorOrbit ;
Next
txv = 0
txu = txu + 1/majorOrbit
Next
;vv.l = MeshVertexCount(1,0)
t=0
For i = 0 To majorOrbit-1
For j = 0 To minorOrbit
MeshFace(t,t+1,t + minorOrbit+1)
MeshFace(t + minorOrbit+1,t + minorOrbit+2,t+1 )
If i=majorOrbit-1 And j=minorOrbit-1 ;bypass the last triangle
minorOrbit-1
EndIf
t + 1
Next
Next
NormalizeMesh(1)
FinishMesh(#False)
;Debug MeshVertexCount(1,0)
;Main loop
MoveNode(node,0,up,depth,#PB_Absolute)
x = 180: y=0: z=0 : h.f
Repeat
Event = WindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case #BUTTON
If rot = 0
rot = 1
rotx= rotx0:roty=roty0:rotz=rotz0 ; restore rotation status
stopFlag = 1
Else
rot = 0
rotx0= rotx:roty0=roty:rotz0=rotz ;back up rotation status
rotx=0:roty=0:rotz=0
stopFlag = 0
EndIf
EndSelect
EndIf
If stopFlag=1
x + rotx
y + roty
z + rotz
EndIf
morph()
RotateNode(node, x, y, z)
RenderWorld()
FlipBuffers()
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Up) ; rotate left
rotx=1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Down) ; rotate right
rotx=-1:roty=0:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Right) ; rotate up
rotx=0:roty=1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
ElseIf KeyboardPushed(#PB_Key_Left) ; rotate down
rotx=0:roty=-1:rotz=0
rotx0 = rotx: roty0 = roty :rotz0 = rotz
x + rotx
y + roty
z + rotz
stopFlag=0
rot = 0
EndIf
If KeyboardPushed(#PB_Key_PageUp) ; scale up model
xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
ScaleNode(node,xs,ys,zs)
ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
xs = 0.9:ys = 0.9:zs= 0.9
ScaleNode(node,xs,ys,zs)
ElseIf KeyboardReleased(#PB_Key_W) ; display wire frame for the material
If wireFrame=0
MaterialShadingMode(0, #PB_Material_Wireframe)
wireFrame ! 1
ElseIf wireFrame=1
MaterialShadingMode(0, #PB_Material_Solid)
wireFrame ! 1
EndIf
EndIf
If KeyboardPushed(#PB_Key_Pad8) ; up move
up + 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad2) ; down move
up - 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad6)
h + 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Pad4)
h - 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_Q) ; forward move
depth - 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
ElseIf KeyboardPushed(#PB_Key_A) ; inward move
depth + 0.1
MoveNode(node,h,up,depth,#PB_Absolute)
EndIf
If KeyboardPushed(#PB_Key_Escape)
Quit = #True
EndIf
Until Quit = #True Or Event = #PB_Event_CloseWindow
Procedure morph()
x.f: y.f :z.f : u.f: v.f: r.f
majorOrbit.l = 50 : minorOrbit.l = 30
majorStep.f = 2 * #PI / majorOrbit
minorStep.f = 2 * #PI / minorOrbit
i.l: j.l :txu.f : txv.f
UpdateMesh(1, 0)
;warping a sphere
;dtime.f=ElapsedMilliseconds()/1200
;--------------------------------
;morphing equations:
;--------------------------------
;vx.f = amplitude * Sin(dtime*freq)
;vy.f = amplitude * Cos(dtime*freq)
;vz.f = amplitude * Sin(dtime*freq)
For i = 0 To majorOrbit
v = i * majorStep
For j = 0 To minorOrbit
u = j * minorStep
;r = 4 * (1 - (Cos(u)/2))
dtime.f=ElapsedMilliseconds()/1200
;--------------------------------
;morphing equations:
;--------------------------------
vx.f = amplitude * Sin(dtime*freq)
vy.f = amplitude * Cos(dtime*freq)
vz.f = amplitude * Sin(dtime*freq)
x = Cos(u) * Cos(v) *vx
y = Sin(u) * Cos(v) *vy
z.f = Sin(v) *vz
MeshVertexPosition(x, y, z);
MeshVertexTextureCoordinate(txu, txv)
MeshVertexNormal(x, y, z)
;texture the whole sphere with one picture stretched
txv = txv + 1/minorOrbit ;
Next
txv = 0
txu = txu + 1/majorOrbit
Next
;vv.l = MeshVertexCount(1,0)
t=0
For i = 0 To majorOrbit-1
For j = 0 To minorOrbit
MeshFace(t,t+1,t + minorOrbit+1)
MeshFace(t + minorOrbit+1,t + minorOrbit+2,t+1 )
If i=majorOrbit-1 And j=minorOrbit-1 ;bypass the last triangle
minorOrbit-1
EndIf
t + 1
Next
Next
NormalizeMesh(1)
FinishMesh(#False)
EndProcedure
Last edited by applePi on Sun Mar 24, 2013 6:51 pm, edited 1 time in total.
Re: Question on MeshVertexPosition()'s speed.
Thank you DarkDragon for the link. I have very little experience when it comes to shaders. I suppose I should start working with them more often.
ApplePi, thanks for those nice examples. I think the best thing I can do is give manual vertex animation a try and hopefully
my calculations won't slow them down to much.
If nothing else I may be able to combine manual and skeletal animations together. That may be the better route, but I think I'll give your way a try first.
Thanks again to both of you!
ApplePi, thanks for those nice examples. I think the best thing I can do is give manual vertex animation a try and hopefully
my calculations won't slow them down to much.
If nothing else I may be able to combine manual and skeletal animations together. That may be the better route, but I think I'll give your way a try first.
Thanks again to both of you!
