I would like to create a "bones system" for animation, in my software Cartoon (Which use the 2D vector drawing).
So, I would like that a shape (box, circle, curve, line...) get some parameters from its "parent" and give some parameters to its children :
- position (x,y)
- rotation
- scale
For Position it's enough simple, and it's ok, even with animation.
But for rotation, I have made some tests, but it doesn't work like I want.
In my code, I would like that the yellow box rotate over the purple box (like the purple rotate over the green box...).
but I don't know how to do that.
I have though to use cos and sin, like with sprite, but I don't know how too.
So any help would be apprecied
Thanks
My test :
Code: Select all
; rotation heritage parenting with lib drawing canvas
; by blendman for "Cartoon !" (open-source 2D vector software)
; pb5.73
Structure sColor
r.a
g.a
b.a
a.a
EndStructure
Structure sParent
id.W
Startx.w
starty.w
EndStructure
Structure sShape
; position
x.d
y.d
; final position with parent heritage
finalx.d
finaly.d
; size
w.w
h.w
; rotation
Rot.d
; final rotation with parent heritage
finalRot.d
; Final rotation center
finalRotcx.d
finalRotcY.d
; color
color.scolor
; center of shape
cx.w
cy.w
; parent shape
parent.sParent
EndStructure
Global Dim shape.SShape(0)
Global nbShape=-1
Procedure AddShape(x,y,w,h,rot,color,cx,cy,parent=-1)
nbShape+1
i=nbshape
ReDim shape(i)
With shape(i)
\x = x
\y = y
\cx = cx
\cy = cy
\w = w
\h = h
\color\a = Alpha(color)
\color\r = Red(color)
\color\g = Green(color)
\color\b = Blue(color)
\Rot = rot
\parent\id = parent
If parent>-1
\parent\Startx = shape(parent)\x
\parent\Starty = shape(parent)\y
EndIf
EndWith
EndProcedure
Procedure updatecanvas()
Static rot.d
Static a
If StartVectorDrawing(CanvasVectorOutput(0))
; background
AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
VectorSourceColor(RGBA(255,255,255,255))
FillPath()
For i=0 To ArraySize(shape())
; display shapes
With shape(i)
ResetCoordinates()
; to calcul the parent heritage : position (x,y) and rotation (rot)
; default rotation of parent
RotParent.d= 0
; get the parentID
p_ID = \parent\id
; if shape has a parent, we have to add the position and rotation from this parent
If p_ID >-1
; the finalrotation of the parent
RotParent = shape(p_ID)\finalRot
; final position
\finalx = shape(p_ID)\x - \parent\startX + shape(p_ID)\finalx
\finaly = shape(p_ID)\y - \parent\starty + shape(p_ID)\finaly
; final center For rotation
\finalRotcx = shape(p_ID)\x + shape(p_ID)\cx-(\x+\cx+\finalx) + shape(p_ID)\finalRotcx + shape(p_ID)\finalx
\finalRotcY = shape(p_ID)\y + shape(p_ID)\cy-(\y+\cy+\finaly) + shape(p_ID)\finalRotcy + shape(p_ID)\finaly
EndIf
; default rotation by shape :
\finalRot = \rot + RotParent
; change rotation for some shapes
If i=0
; we rotate the box_0
\finalRot = \rot + rot + RotParent
; animation of the positon X (for the Shape0)
\x +a
If a= 0
a=1
EndIf
If \x> 500
a=-1
Else
If \x<=50
If a<0
a=1
EndIf
EndIf
EndIf
ElseIf i = 1
; the box_1 isn't rotated
\finalRot = \rot + RotParent
ElseIf i = 2
; the box_2 should be rotated
; if I do a 2nd rotation, it doesn't work
\finalRot = \rot +RotParent
EndIf
; then rotate the coordinates
If \finalRot <> 0
; RotateCoordinates(\x+\cx+\finalRotcx,\y+\cy+\finalRotcy,\finalRot)
RotateCoordinates(\x+\cx+\finalx+\finalRotcx,\y+\cy+\finaly+\finalRotcy,\finalRot)
If i=2
; doesn't work
; \finalRot + rot
; RotateCoordinates(\x+\cx,\y+\cy,\finalRot)
; doesn't work
RotateCoordinates(\x+\cx+\finalx,\y+\cy+\finaly, Rot)
EndIf
EndIf
; display the shapes
MovePathCursor(\x,\y)
AddPathBox(\x+\finalx,\y+\finaly,\w,\h)
VectorSourceColor(RGBA(\color\r,\color\g,\color\b,\color\a))
FillPath()
AddPathCircle(\x+\cx+\finalx,\y+\cy+\finaly,5)
VectorSourceColor(RGBA(50,0,0,200))
FillPath()
EndWith
Next
rot+0.2
StopVectorDrawing()
EndIf
EndProcedure
w=1024
h=600
If OpenWindow(0, 0, 0, w, h, "VectorDrawing rotation heritage & parenting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, w, h)
x = 450
y = 300
AddShape(x,y,100,80,0,RGBA(200,100,50,255),25,25) : x+100
AddShape(x,y,150,60,0,RGBA(00,100,50,255),25,25,0) : x+100
AddShape(x,y,120,50,0,RGBA(100,00,150,255),25,25,1): x+100
AddShape(x,y,100,40,0,RGBA(255,255,0,255),25,25,2)
updatecanvas()
Repeat
Repeat
Event = WaitWindowEvent(1)
Until event = 0 Or Event = #PB_Event_CloseWindow
updatecanvas()
Until Event = #PB_Event_CloseWindow
EndIf