Animated Vector Graphics Scene Graph

Share your advanced PureBasic knowledge/code with the community.
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

This almost works, maybe Fred should add

Code: Select all

GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count)

so we can use an array of points

Code: Select all

Structure avgpoint
  x.f
  y.f
EndStructure  

Procedure _AVGRefit_Bezier(*p0.avgpoint,*p1.avgpoint,*p2.avgpoint,*p3.avgpoint,*t0.avgpoint,*t1.avgpoint)
  
  Protected d1.f, d2.f, d3.f
  Protected a.f, b.f, c.f, d.f
  Protected tx1.f,ty1.f,tx2.f,ty2.f
  
  d1 = Sqr((*p1\x-*p0\x)*(*p1\x-*p0\x) + (*p1\y-*p0\y)*(*p1\y-*p0\y))*0.5
  d2 = Sqr((*p2\x-*p1\x)*(*p2\x-*p1\x) + (*p2\y-*p1\y)*(*p2\y-*p1\y))*0.5 
  d3 = Sqr((*p3\x-*p2\x)*(*p3\x-*p2\x) + (*p3\y-*p2\y)*(*p3\y-*p2\y))*0.5 
  
  a = d1 * d1
  b = d2 * d2
  c = (2 * d1 * d1) + (3 * d1 * d2) + (d2 * d2)
  d = 1.0 / (3 * d1 * (d1 + d2))
  
  *t0\x = (a * *p2\x - b * *p0\x + c * *p1\x) * d
  *t0\y = (a * *p2\y - b * *p0\y + c * *p1\y) * d
  
  a = d3 * d3
  b = d2 * d2
  c = (2 * d3 * d3) + (3 * d3 * d2) + (d2 * d2)
  d = 1.0 / (3 * d3 * (d3 + d2))
  
  *t1\x = (a * *p1\x - b * *p3\x + c * *p2\x) * d
  *t1\y = (a * *p1\y - b * *p3\y + c * *p2\y) * d
  
EndProcedure

Procedure AVGAddPathPolygonBezier(x,y,sides.i,majoraxis.i,minoraxis.i=0,orient.i=0,Stars=1,bPathCurve=0)
    
  Protected xx, yy, px, py, inc.f, ang.f, fin.f
  Protected ndx.f,ndy.f,dy.f,dx.f,dx1,dy1,cosOrient.f,SinOrient.f
  Protected start.i,finish.i,dz.f,i.i
  Protected t0.avgpoint,t1.avgpoint  
  
  start = 0 
  If stars 
    sides*2 
  EndIf   
  
  Dim pt.avgpoint(sides) 
  
  dz=1.0
  finish = sides 
  If finish < 3 : finish = 3 : EndIf
  If finish > 64 : finish = 64 : EndIf
  inc = Radian(360 / finish)
  finish = start + 360
  
  ang = Radian(start)
  fin = Radian(finish)
  cosOrient = Sin(Radian(orient-180)) 
  sinOrient = Cos(Radian(orient-180))  
  dx = x + (Cos(ang) * majoraxis * dz) 
  dy = y + (Sin(ang) * minoraxis * dz) 
  dx1 = dx - x 
  dy1 = dy - y
  px = x + (dx1 * sinOrient - dy1 * cosOrient) ;rotate coordinates
  py = y + (dx1 * cosOrient + dy1 * sinOrient) 
  If stars 
    dz = 0.5 
  EndIf   
  
  Protected first=0  
  i=0
  Repeat 
    
    ang + inc  
    If ang > fin : ang = fin : EndIf
    dx = x + (Cos(ang) * majoraxis * dz) 
    dy = y + (Sin(ang) * minoraxis * dz) 
    dx1 = dx - x 
    dy1 = dy - y
    ndx = x + (dx1 * sinOrient - dy1 * cosorient) 
    ndy = y + (dx1 * cosOrient + dy1 * sinorient)
    
    pt(i)\x = ndx 
    pt(i)\y = ndy 
    i+1
    
    px = ndx
    py = ndy
    
    If stars 
      If dz = 0.5 
        dz = 1.0 
      Else 
        dz = 0.5 
      EndIf   
    EndIf 
  Until ang = fin
  
  Protected segments.s 
  
  sides = ArraySize(pt())
  For i = 0 To sides
    
    _AVGRefit_Bezier(pt(i%sides),pt((i+1)%sides),pt((i+2)%sides),pt((i+3)%sides),t0,t1) 
    MovePathCursor(pt((i+1)%sides)\x,pt((i+1)%sides)\y)
    
    If bPathCurve=0 
      AddPathCurve(t0\x,t0\y,t1\x,t1\y,pt((i+2)%sides)\x,pt((i+2)%sides)\y)
    Else   
      segments + " C " + StrF(t0\x, 2) + "," + StrF(t0\y, 2) + " " + StrF(t1\x, 2) + "," + StrF(t1\y, 2) + " " + StrF(pt((i+2)%sides)\x, 2) + "," + StrF(pt((i+2)%sides)\y, 2)
    EndIf 
  
    Next
   
    segments + " Z"
    
  If bPathCurve = 1   
   AddPathSegments(segments)
  EndIf 
  
EndProcedure

OpenWindow(0, 0, 0, 500, 500, "VectorDrawing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 500, 500)

StartVectorDrawing(CanvasVectorOutput(0))

TranslateCoordinates(250,250)
MovePathCursor(0,0)

AVGAddPathPolygonBezier(0,0,5,50,50,17,1,1) ;0 uses AddPathCurve 1 uses AddPathSegments 

ClosePath()
VectorSourceColor($ff0000ff)
FillPath(#PB_Path_Preserve)
VectorSourceColor($ffff0000)
StrokePath(2)

StopVectorDrawing()

Repeat
  Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow

User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

sneak preview of SVG integration
https://atomicwebserver.com/avgscenegraph.mp4

Think it's time I add image caching as it's a bit hungry on cpu pulling 5.91% and 6.60% full screen.


Image
User avatar
SPH
Enthusiast
Enthusiast
Posts: 612
Joined: Tue Jan 04, 2011 6:21 pm

Re: Animated Vector Graphics Scene Graph

Post by SPH »

idle wrote: Tue Oct 28, 2025 8:22 pm sneak preview of SVG integration
https://atomicwebserver.com/avgscenegraph.mp4
Unfortunately, the video doesn't start...

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 6.12LTS - 64 bits
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

SPH wrote: Tue Oct 28, 2025 9:07 pm
idle wrote: Tue Oct 28, 2025 8:22 pm sneak preview of SVG integration
https://atomicwebserver.com/avgscenegraph.mp4
Unfortunately, the video doesn't start...
The server doesn't support range requests or maybe it timed out.
works on edge, firefox, chrome on windows desktop and andriod with chrome
I will put on github soon
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

updated v0.3.1a
Added SVG support

There's lots to do
still issues with AVGAddPathPolygonBezier
Event quirks

It's starting to look a bit better now. working from the bottom up does my head in but the result is pretty neat
in that you can modify any element on the fly like the Tigers eyes

download
https://atomicwebserver.com/AVGSceneGraph.zip
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 426
Joined: Thu Jul 09, 2015 9:07 am

Re: Animated Vector Graphics Scene Graph

Post by pf shadoko »

Very impressive!
But it would require hardware acceleration.

I looked into it, and NanoVG (not to be confused with nanoSVG) implements the JavaScript canvas function set (including fonts).

https://www.youtube.com/watch?v=c8IsoDQ7ea8

If someone with the necessary knowledge could take on this task, it would enable hardware acceleration in the VectorDrawing library.
I'll take care of the canvas->vectordrawing conversion (I've already done it for SpiderBasic).


PS: Following our conversation, I posted an “addpathspline” function (which converts splines to bezier curves).
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

No need to yell, i sent you a link to nanovg because it does antialiasing lines which you wanted for vectors in 3d and I do plan to add opengl bindings to this later but it's not just a case of more power. It needs image caching
PS: Following our conversation, I posted an “addpathspline” function (which converts splines to bezier curves).
Thanks I tried that and still had the same problems as you need to refit the curve to follow the control points.

and we should be able to use nanovg directly though it will take some thought to mate it and I don't know yet how it does the hit tests

Code: Select all

nvgBeginPath(vg);
nvgRect(vg, 100,100, 120,30);
nvgCircle(vg, 120,120, 5);
nvgPathWinding(vg, NVG_HOLE);	// Mark circle as a hole.
nvgFillColor(vg, nvgRGBA(255,192,0,255));
nvgFill(vg);
Justin
Addict
Addict
Posts: 961
Joined: Sat Apr 26, 2003 2:49 pm

Re: Animated Vector Graphics Scene Graph

Post by Justin »

3d acceleration will be great, it will also increase ram, probably 200mb on 4k at full screen :)
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

Justin wrote: Wed Oct 29, 2025 8:26 pm 3d acceleration will be great, it will also increase ram, probably 200mb on 4k at full screen :)
I'm not good at explaining. People want SVG and animated SVG but to get animated SVG you need a DOM or an engine and its independent of the surface and to achieve this you need a runtime which is what it is. It's also designed so there's no need to learn another api and you don't need to link another lib into your exe. Later it can work on opengl by replacing the rtFunctions to handle the opengl functions which should work perfectly fine in immediate mode, then you can target any vector surface, canvas or opengl gadget, screen so it's useable along side the standard gadgets, it may also be possible to bolt into spider basic and give you control over the elements without js.

You can use it as an infinite canvas or not, the key is it doesn't restrict you and that's the point, there's nothing more irritating than having one hand tied behind your back because someone didn't think about it and painted them selves into a corner. You will be able to use it to make and editor to edit and compose graphics, live drag drop point and click, select any element of the graphic and modify it, make UI elements and controls and it doesn't add much overhead either, you can make multiple scenes with multiple objects, It doesn't need to be full screen and updated at 60 fps that's not really the intended purpose of it yet, but it has to be capable of those things out the box and and then it can be built upon to do those things but you don't want another 3k lines of code just to put an icon on a window or make a chart or table only to find it doesn't work on a canvas or screen and you don't need to animate everything all the time either, it can be done where and when required.

To make it efficient on canvas it needs caching added, I'm under no illusion that it will struggle on a single thread currently as its redrawing the display list each time but it's a painter algorithm you only need to change what's above, so if the hit test is at id(200) of an object it only has to redraw that item of that object if it's not cached. So blit cached image, goto 200 directly via pointer and draw it or blit the cached fragment. Secondly object rendering can be threaded on gdi, there is no need for it to draw directly to the target surface so you can use a thread pool to render objects ready for blitting and still get the hit tests and utilize all the cores. so it's final draw is to the target. Each objects image can be cached and each fragment of an object can be cached on the object items themselves and it doesn't need much to add that. The hit tests of cached fragments only requirer translating the coordinates to the cached image and it's fragments and then it's just a getpixel point test. Changes of scale or rotation to an object will force a full redraw then back to cache. The key part is you will only redraw the vectors on change so it will be capable of doing 60FPS as it'll mostly be bliting on canvas or sprites or just immediate mode in opengl. If it's just a spinning wait icon it's not going to matter if it's cached or redrawn but to scale it needs basic caching.

Right now the aim is to get the core functionality working then the bindings to opengl can be made then I can look at the caching for gdi.
User avatar
minimy
Enthusiast
Enthusiast
Posts: 728
Joined: Mon Jul 08, 2013 8:43 pm
Location: off world

Re: Animated Vector Graphics Scene Graph

Post by minimy »

Your new additions to the library are very good. Simply amazing! :shock:
Thanks for share!
If translation=Error: reply="Sorry, Im Spanish": Endif
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

minimy wrote: Thu Oct 30, 2025 1:49 am Your new additions to the library are very good. Simply amazing! :shock:
Thanks for share!
Thanks it's getting closer

I will look into building nanovg next week so we can experiment with that as a backend, might calm pf shadoko down :lol:
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 426
Joined: Thu Jul 09, 2015 9:07 am

Re: Animated Vector Graphics Scene Graph

Post by pf shadoko »

idle wrote: Thu Oct 30, 2025 3:14 am I will look into building nanovg next week so we can experiment with that as a backend, might calm pf shadoko down :lol:
See, it pays to yell!

As for image caching, it seems complicated to me, since animations can be interspersed between fixed layers.
But hey, you know your stuff...
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

pf shadoko wrote: Thu Oct 30, 2025 11:20 am
idle wrote: Thu Oct 30, 2025 3:14 am I will look into building nanovg next week so we can experiment with that as a backend, might calm pf shadoko down :lol:
See, it pays to yell!

As for image caching, it seems complicated to me, since animations can be interspersed between fixed layers.
But hey, you know your stuff...
It's not that complicated but the problem is all here in my ass as I point to my head! (a punch line from an old french joke)
User avatar
idle
Always Here
Always Here
Posts: 6075
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Animated Vector Graphics Scene Graph

Post by idle »

I've been experimenting with threading which has got the load off the window thread but even so i still see a lag as it's governed by the longest running render thread the Tiger which has a lot of paths and takes around 80ms to render vs the rest which are around 20 to 30ms, make the tiger static and your down to around 30ms per frame.
So now I need to look at fragment caching eg the eyes of the tiger so it renders the highlight on mouse over.

Looking at nanovg it has to be staticly linked to work and my initial attempt haven't worked.
Post Reply