Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/kinematic.py
blob: d5442a20776ae42af5a09cb672c03ae8501183b5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

import model
import theme

class KinematicFrame:
    def __init__(self, keyframe=None):
        if keyframe:
            self.assign(keyframe)
        else:
            self.joints = None
            self.parts = None
            self.middle = None
            self.hsize = None

    def assign(self, keyframe):
        self.joints = keyframe.joints.copy()
        self.parts = keyframe.parts.copy()
        self.middle = keyframe.middle
        self.hsize = keyframe.sticks['HEAD'][1]

def makeframes():
    frames = {}

    for i in model.keys:
        if not i.empty():
            frames[i.x] = KinematicFrame(i)

    if not frames:
        return {}

    fsecs = frames.keys()
    fsecs.sort()

    # set border frames
    frames[0] = frames[fsecs[0]]
    frames[theme.KEYFRAMEWIDTH] = frames[fsecs[-1]]

    # now fill in frames between
    fsecs = frames.keys()
    fsecs.sort()

    # frame interval
    fint = int(theme.KEYFRAMEWIDTH/float(theme.TOTALFRAMES)) 

    for i in range(len(fsecs)):
        if i == len(fsecs)-1:
            continue # nothing after end

        startsecs = fsecs[i]
        endsecs = fsecs[i+1]
        start_frame = frames[startsecs]
        end_frame = frames[endsecs]
        numframes = int((endsecs-startsecs)/float(fint))-1

        for j in range(numframes-1): # MAYBE SHOULD BE numframes
            frame = frames[startsecs + ((j+1)*fint)] = KinematicFrame()

            frame.joints = _intjoints(start_frame.joints, end_frame.joints,
                    j+1, numframes)
            frame.parts = _intparts(start_frame.parts, end_frame.parts,
                    j+1, numframes)
            frame.middle = _intmiddle(start_frame.middle, end_frame.middle,
                    j+1, numframes)
            frame.hsize = _inthsize(start_frame.hsize, end_frame.hsize,
                    j+1, numframes)

    return frames

def _interpolate(x,x0,y0,x1,y1):
    if x1-x0 == 0:
        return y0
    m = float(y1-y0)/float(x1-x0)
    y = y0 + ((x-x0)*m)
    return y

def _intjoints(sjoints, ejoints, count, numpoints):
    # numpoints: number of points between start and end
    # count: point were getting now
    ijoints = {}
    for jname in sjoints:
        (x0,y0) = sjoints[jname]
        (x1,y1) = ejoints[jname]
        #print 'x0:%s,y0:%s' % (x0,y0)
        #print 'x1:%s,y1:%s' % (x1,y1)
        x = x0 + (count * ((x1-x0)/float(numpoints)))
        y = _interpolate(x,x0,y0,x1,y1)
        ijoints[jname] = (int(x),int(y))
    return ijoints

def _intparts(sparts,eparts,count,numpoints):
    iparts = {}
    for pname in sparts:
        x0 = sparts[pname]
        x1 = eparts[pname]
        if x0 == x1:
            iparts[pname] = x0
            continue
        x = x0 + (count * ((x1-x0)/float(numpoints)))
        iparts[pname] = int(x)
    return iparts

def _intmiddle(smiddle,emiddle,count,numpoints):
    (x0,y0) = smiddle
    (x1,y1) = emiddle
    x = x0 + (count * ((x1-x0)/float(numpoints)))
    y = _interpolate(x,x0,y0,x1,y1)
    return (int(x),int(y))

def _inthsize(shsize,ehsize,count,numpoints):
    x0 = shsize
    x1 = ehsize
    if x0 == x1:
        return x0
    x = x0 + (count * ((x1-x0)/float(numpoints)))
    return int(x)