comparison pyink/MBScene.py @ 1123:aad659b6b625

Add motion animation editor.
author wycc
date Thu, 09 Dec 2010 07:48:08 +0800
parents 214e1f628d63
children 5b2394f67ad0
comparison
equal deleted inserted replaced
1122:3d438daea48c 1123:aad659b6b625
427 pass 427 pass
428 pass 428 pass
429 429
430 430
431 def setCurrentScene(self,nth): 431 def setCurrentScene(self,nth):
432 """
433 Update the scene group according to the curretn scene data. There are a couple of cases.
434 1. If the type of the scene is normal, we display it when it contains the current
435 frame. Otherwise hide it.
436 2. If the type of the scene is relocate or scale, we need to duplicate the scene group
437 and then modify its transform matrix according to the definition of the scene. Then,
438 hide the original scenr group and display the duplciate scene group. In addition,
439 we may need to delete the old duplicated scene group as well.
440
441 For each layer, we will always use the duplicated scene group whose name as dup.
442 We will put the duplicated scene group inside it. We will create this group if it is not
443 available.
444 """
432 self.current = nth 445 self.current = nth
433 for layer in self._framelines: 446 for layer in self._framelines:
434 i=0 447 i=0
448
449 # Check the duplicated scene group and create it if it is not available
450 try:
451 if layer.duplicateGroup:
452 layer.duplicateGroup.parent().removeChild(layer.duplicateGroup)
453 layer.duplicateGroup = None
454 except:
455 traceback.print_exc()
456 pass
457 # Create a new group
458 layer.duplicateGroup = None
459
460
435 while i < len(layer._keys): 461 while i < len(layer._keys):
436 s = layer._keys[i] 462 s = layer._keys[i]
437 print s.ref.attribute("id"),s.idx,s.left_tween,s.right_tween 463 print s.ref.attribute("id"),s.idx,s.left_tween,s.right_tween
438 if s.right_tween is False: 464 if s.right_tween is False:
439 if nth == s.idx+1: 465 if nth == s.idx+1:
440 s.ref.setAttribute("style","",True) 466 s.ref.setAttribute("style","",True)
441 else: 467 else:
442 s.ref.setAttribute("style","display:none",True) 468 s.ref.setAttribute("style","display:none",True)
443 i = i + 1 469 i = i + 1
444 continue 470 continue
445 471 if nth == s.idx + 1:
446 if nth >= (s.idx+1) and nth <= (layer._keys[i+1].idx+1):
447 s.ref.setAttribute("style","",True) 472 s.ref.setAttribute("style","",True)
448 else: 473 else:
449 s.ref.setAttribute("style","display:none",True) 474 if nth > (s.idx+1) and nth <= (layer._keys[i+1].idx+1):
475 if i+2 < len(layer._keys):
476 layer.duplicateGroup = self.desktop.doc().rdoc.createElement("svg:g")
477 layer.duplicateGroup.setAttribute("inkscape:label","dup",True)
478 s.ref.setAttribute("style","display:none",True)
479 s.ref.parent().appendChild(layer.duplicateGroup)
480 self.updateTweenContent(layer.duplicateGroup, layer.get_tween_type(s.idx),s, layer._keys[i+2], nth)
481 else:
482 s.ref.setAttribute("style","display:none",True)
450 i = i + 2 483 i = i + 2
451 pass 484 pass
485 pass
486 pass
487 def updateTweenContent(self,obj, typ, source,dest,cur):
488 """
489 Update the content of the duplicate scene group. We will use the (start,end) and cur to calculate the percentage of
490 the tween motion effect and then use it to update the transform matrix of the duplicated scene group.
491 """
492 start = source.idx
493 end = dest.idx
494 print cur,start,end
495 percent = (cur-start)*1.0/(end-start)
496 i = 0
497 s = source.ref.firstChild()
498 d = dest.ref.firstChild()
499 sources={}
500 dests={}
501 # Collect all objects
502 while d:
503 try:
504 label = d.attribute("inkscape:label")
505 except:
506 d = d.next()
507 continue
508 dests[label.value()] = d
509 d = d.next()
510 # Check if the object in the source exists in the destination
511 s = source.ref.firstChild()
512 d = dest.ref.firstChild()
513 while s:
514 print s,d
515 try:
516 label = s.attribute("inkscape:label")
517 # Use i8nkscape:label to identidy the equipvalent objects
518 if label:
519 if dests.hasattr(label.value()):
520 self.updateTweenObject(obj,typ,s,dests[label.value()],percent)
521 s = s.next()
522 continue
523 except:
524 pass
525 # Search obejcts in the destination
526 while d:
527 try:
528 d.attribute("inkscape:label")
529 d = d.next()
530 continue
531 except:
532 pass
533 if s.name() == d.name():
534 self.updateTweenObject(obj,typ,s,d,percent)
535 d = d.next()
536 break
537 d = d.next()
538 s = s.next()
539 def parseTransform(self,obj):
540 """
541 Return the transform matrix of an object
542 """
543 try:
544 t = obj.attribute("transform")
545 print t
546 if t[0:9] == 'translate':
547 print "translate"
548 fields = t[10:].split(',')
549 x = float(fields[0])
550 fields = fields[1].split(')')
551 y = float(fields[0])
552 return [1,0,x,0,1,y]
553 elif t[0:6] == 'matrix':
554 print "matrix"
555 fields=t[7:].split(')')
556 fields = fields[0].split(',')
557 return [float(fields[0]),float(fields[1]),float(fields[2]),float(fields[3]),float(fields[4]),float(fields[5])]
558 except:
559 traceback.print_exc()
560 return [1,0,0,0,1,0]
561
562
563 def updateTweenObject(self,obj,typ,s,d,p):
564 """
565 Generate tweened object in the @obj by using s and d in the @p percent
566 """
567 print 'compare',s,d
568 if typ == 'relocate':
569 print "percent",p
570 newobj = s.duplicate(self.desktop.doc().rdoc)
571 top = self.desktop.doc().rdoc.createElement("svg:g")
572 top.appendChild(newobj)
573 obj.appendChild(top)
574 print s.name()
575 if s.name() == 'svg:g':
576 # Parse the translate or matrix
577 sm = self.parseTransform(s)
578 dm = self.parseTransform(d)
579 print "g", (dm[2]-sm[2])*p,(dm[5]-sm[5])*p
580 top.setAttribute("transform","translate(%g,%g)" % ((dm[2]-sm[2])*p,(dm[5]-sm[5])*p),True)
581 else:
582 try:
583 sx = float(s.attribute("x"))
584 sy = float(s.attribute("y"))
585 dx = float(d.attribute("x"))
586 dy = float(d.attribute("y"))
587 tx = (dx-sx)*p
588 ty = (dy-sy)*p
589 print tx,ty
590 top.setAttribute("transform","translate(%g,%g)" % (tx,ty),True)
591 except:
592 traceback.print_exc()
593 pass
452 pass 594 pass
453 pass 595 pass
454 def enterGroup(self,obj): 596 def enterGroup(self,obj):
455 for l in self.layers: 597 for l in self.layers:
456 for s in l.node.childList(): 598 for s in l.node.childList():